Skip to content

feat: 답변 이미지 WebP 변환 및 리사이징 파이프라인 추가#160

Merged
1Seob merged 2 commits into
developfrom
feat/answer-image-webp-resize
May 6, 2026
Merged

feat: 답변 이미지 WebP 변환 및 리사이징 파이프라인 추가#160
1Seob merged 2 commits into
developfrom
feat/answer-image-webp-resize

Conversation

@1Seob
Copy link
Copy Markdown
Collaborator

@1Seob 1Seob commented May 6, 2026

📝 요약(Summary)

변경 이유

기존에는 사용자가 업로드한 PNG/JPEG 원본 이미지 key를 그대로 DB에 저장했습니다.
이 방식은 이미지 용량이 커질수록 S3 저장 비용과 CloudFront 전송 비용이 증가할 수 있습니다.

이번 변경을 통해 최종 제공용 이미지는 WebP 형식으로 리사이징하여 저장하고, DB에는 WebP key만 저장하도록 개선했습니다.
원본 이미지는 변환 처리용으로만 사용하고 Lifecycle로 제거하여 저장 비용을 줄일 수 있습니다.

작업 내용

  • 답변 이미지 업로드 시 원본 이미지와 WebP 변환본 key를 분리했습니다.
  • Presigned URL 발급 응답에 objectKey, webpKey를 함께 반환하도록 변경했습니다.
  • S3 answers/original/ 경로에 이미지가 업로드되면 Lambda가 실행되어 WebP 변환본을 answers/webp/ 경로에 생성하도록 구성했습니다.
  • 답변 생성 이후 answer_entries.image_key에는 webpKey가 저장됩니다.
  • 이미지 처리 완료 여부를 확인하기 위해 S3 HeadObject 기반 상태 확인 API를 추가했습니다.
  • 답변 생성 시 webpKey가 현재 사용자 경로에 속하는지, 실제 S3에 존재하는지 검증하도록 했습니다.
  • 원본 이미지는 S3 Lifecycle을 통해 일정 기간 이후 자동 삭제되도록 구성했습니다.

주요 흐름

  1. 서버가 Presigned URL과 함께 objectKey, webpKey를 반환합니다.
  2. 프론트가 objectKey 위치에 PNG/JPEG 원본 이미지를 업로드합니다.
  3. S3 ObjectCreated 이벤트로 Lambda가 실행됩니다.
  4. Lambda가 원본 이미지를 리사이징하고 WebP로 변환합니다.
  5. 변환본은 answers/webp/{userId}/{uuid}.webp 경로에 저장됩니다.
  6. 프론트는 이미지 상태 확인 API로 webpKey 생성 여부를 확인합니다.
  7. 처리 완료 후 답변 생성 API에 objectKeywebpKey를 전달합니다.
  8. 서버는 답변 생성 이후 answer_entries.image_keywebpKey를 저장합니다.
  9. 원본 이미지는 S3 Lifecycle 정책에 따라 자동 삭제됩니다.

🔗 Related Issue

  • Closes:

💬 공유사항

✅ PR Checklist

PR이 다음 요구 사항을 충족하는지 확인하세요.

  • PR 제목을 커밋 메시지 컨벤션에 맞게 작성했습니다.

@coldsunn
Copy link
Copy Markdown
Collaborator

coldsunn commented May 6, 2026

굳굳 머지 고고~

@1Seob 1Seob merged commit 2d28398 into develop May 6, 2026
1 check passed
@1Seob 1Seob deleted the feat/answer-image-webp-resize branch May 6, 2026 05:41
1Seob added a commit that referenced this pull request May 7, 2026
* feat: 답변에 이미지 업로드 추가 및 탈퇴 사용자 이미지 정리 추가 (#154)

* feat: answer_entries 테이블에 image_key 컬럼 추가

AnswerEntry 엔티티에 imageKey 필드 추가

* feat: 기존 AnswerEntry 생성 및 조회 비즈니스 로직에 imageKey 추가

* feat: 답변 이미지 업로드 PresignedURL 생성 api 구현

* feat(report): DailyReportLlmClient 수정

이미지 포함 여부에 따라 프롬프트 및 UserMessage 분기 처리

* feat(report): 일간 리포트 조회 로직 및 응답에 이미지 포함

* feat(user): User 영구 삭제 시 프로필 이미지와 답변 이미지들을 S3에서 삭제하는 로직 추가

UserCleanupScheduler에서 삭제 대상 회원들의 프로필 이미지 키와 답변 이미지 키를 모두 수집하여 S3에서 삭제

* docs(report): 오늘의 리포트 생성 API의 스웨거 문서 수정

이미지 포함 시에 대한 설명 추가

* fix: 코드 리뷰 반영

UserCleanupScheduler에서 삭제 대상 ID가 없으면 조기 종료하도록 처리, DailyReportService의 contentType 검증 중복 코드를 제거하고
switch default 예외 처리로 통합, SecretDailyReportPromptLoader에서 with-image 프롬프트 검증 대상을 rawWithImagePrompt로
수정 등

* chore(notify): backfill 완료 후 NotificationSettingBackfillRunner 제거 (#157)

* fix: 일일 질문 문구 오타 및 어색한 표현 수정 (#158)

* feat: 질문 API/도메인 V2 구현 (#159)

* feat: user_daily_questions 테이블에 reroll_left 컬럼 및 엔티티 필드 추가

기존 데이터 reroll_left = 0 백필, 신규 데이터 기본값 5, NOT NULL 적용, UserDailyQuestion 엔티티에 rerollLeft 필드 및 초기값 반영

* feat: 오늘의 질문 조회 V2 API 구현

* feat: 오늘의 질문 조회 V2 API 구현

* feat(infra): 개발 환경 Swagger UI 태그 정렬 방식 설정

* fix: reroll_left의 백필 값을 5로 변경

* feat: 답변 이미지 WebP 변환 및 리사이징 파이프라인 추가 (#160)

* feat(report): 일간 리포트의 이미지 업로드 로직에 webp 추가

* feat(report): 답변 이미지(webp) 상태 조회 API 구현

* feat(db): 일일 질문 리스트 변경사항 반영 마이그레이션 추가 (#161)

---------

Co-authored-by: Chanhae Lee <146611988+coldsunn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants