Skip to content

[Feat] 페이지 스냅샷 추가#46

Open
minsoo0506 wants to merge 1 commit into
devfrom
feat/#45-page-snapshot
Open

[Feat] 페이지 스냅샷 추가#46
minsoo0506 wants to merge 1 commit into
devfrom
feat/#45-page-snapshot

Conversation

@minsoo0506

@minsoo0506 minsoo0506 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

요약

링크 검사 결과에서 사용자가 최종 URL의 페이지 화면을 확인할 수 있도록 페이지 스냅샷 생성 기능을 추가했습니다. 스냅샷 이미지를 API 응답에 직접 포함하지 않고, 서버 로컬 저장소에 PNG로 저장한 뒤 응답에는 스냅샷 상태와 storage_key를 내려주는 방식입니다. (임시)

주요 변경 사항:

  • PageSnapshotResult, PageSnapshotStatus 스키마 추가
  • PipelineSuccess.snapshot 응답 필드 추가
  • Playwright 기반 페이지 스냅샷 생성 서비스 추가
  • 정상 검사 경로에서 콘텐츠 분석과 스냅샷 생성을 병렬 실행
  • threat DB 매치 등으로 위험 판정이 이미 확정된 경우 스냅샷 생성 스킵
  • 스냅샷 실패/타임아웃이 verdict, score, summary에 영향을 주지 않도록 분리
  • 기본 스냅샷 대기 시간을 1초로 제한해 파이프라인 응답 지연을 방지
  • 스냅샷 상태를 available, skipped, timeout, failed로 구분

응답 :

{
  "status": "success",
  "verdict": "safe",
  "score": 0,
  "summary": "현재 분석 기준에서 뚜렷한 위험 신호가 확인되지 않았습니다.",
  "snapshot": {
    "status": "available",
    "final_url": "https://example.com/",
    "storage_key": "aid-snapshot.png",
    "elapsed_seconds": 0.83,
    "error": null
  }
}

이미지 전달 방식 검토

1. S3/R2/GCS 등 객체 스토리지 사용

흐름:

  1. FastAPI가 최종 URL 페이지 스냅샷을 PNG로 생성
  2. PNG를 S3 같은 객체 스토리지에 업로드
  3. 응답에는 snapshot_url 또는 storage_key 반환
  4. 프론트엔드는 해당 URL로 이미지를 표시
  5. 일정 시간이 지나면 lifecycle rule 또는 백엔드 cleanup job으로 삭제

예시 응답:

{
  "snapshot": {
    "status": "available",
    "final_url": "https://example.com/",
    "storage_key": "snapshots/analysis-id.png",
    "snapshot_url": "https://cdn.example.com/snapshots/analysis-id.png",
    "elapsed_seconds": 0.83
  }
}

장점:

  • API 응답 크기가 작음
  • 프론트에서 일반 이미지처럼 로드 가능
  • CDN 캐싱 가능
  • 만료/삭제 정책 적용 쉬움
  • 다중 서버 환경에서도 안정적
  • 이미지 재조회가 쉬움

삭제 방식 예시:

  • S3 lifecycle rule로 snapshots/ prefix 파일을 1일 후 자동 삭제
  • 또는 분석 결과 조회 가능 시간이 짧다면 10분~1시간 TTL 적용
  • 민감 페이지 가능성을 고려하면 public bucket보다는 presigned URL 방식 권장

운영 방식:

FastAPI -> S3 private bucket 업로드 -> presigned URL 발급 -> 프론트 표시 -> TTL 후 만료/삭제

2. base64 inline 응답

이미지를 API 응답 JSON 안에 직접 넣는 방식입니다.

예시:

{
  "snapshot": {
    "status": "available",
    "mime_type": "image/png",
    "base64": "iVBORw0KGgoAAAANSUhEUg...",
    "elapsed_seconds": 0.83
  }
}

장점:

  • 별도 저장소가 필요 없음
  • 프론트가 즉시 data:image/png;base64,...로 표시 가능
  • MVP나 내부 테스트에는 단순함

단점:

  • PNG 원본보다 약 33% 커짐
  • API 응답 크기가 커짐
  • callback, 로그, APM, gateway body size 제한에 걸릴 수 있음
  • 캐싱/재조회/삭제 개념이 애매함
  • 여러 사용자가 동시에 요청하면 네트워크 비용이 커짐

현실적인 사용 조건:

  • 스냅샷이 1장이고 수백 KB 수준
  • 내부 테스트 또는 MVP
  • 응답 크기 제한을 명확히 둠

예시 제한:

page_snapshot_inline_max_bytes = 500_000

3. FastAPI 로컬 디스크 + 정적 파일 서빙

흐름:

  1. FastAPI 서버 로컬 디스크에 PNG 저장
  2. /static/snapshots/{id}.png 같은 URL로 제공
  3. 응답에는 해당 경로 반환

장점:

  • 구현이 단순함
  • 개발/스테이징 테스트에 적합
  • S3 없이 바로 확인 가능

단점:

  • 운영 다중 인스턴스 환경에서 문제가 생김
  • 서버 재시작/배포 시 파일 유지가 불안정함
  • 디스크 cleanup 필요
  • CDN/접근 제어/만료 처리가 번거로움

성능 테스트 결과

실제 정상 URL 10개를 대상으로 스냅샷 생성 테스트를 수행했습니다.

테스트 URL:

스크린샷 2026-07-07 오후 5 34 36

@minsoo0506
minsoo0506 requested review from kbh0218 and sunm2n July 8, 2026 13:01
@minsoo0506 minsoo0506 self-assigned this Jul 8, 2026
@minsoo0506 minsoo0506 added the feature 새로운 기능/특징 label Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 새로운 기능/특징

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] 링크 검사 결과에 페이지 스냅샷 제공

1 participant