-
Notifications
You must be signed in to change notification settings - Fork 1
[Portfolio] 동기 이미지 압축 MVP 초기 세팅 #74
Description
배경
포트폴리오 계획의 시작점은 동기 압축이 이미 설계된 상태여야 한다. 현재 우리 프로젝트는 게시글 이미지 업로드 기능은 이미 존재하지만, 업로드된 이미지를 후처리 없이 그대로 저장/노출하는 구조다.
현재 흐름은 대략 아래와 같다.
- 클라이언트가 게시글 이미지용 presigned URL 발급 요청
- 서버가 S3 object key와 presigned URL 반환
- 클라이언트가 S3에 직접 업로드
POST /api/posts요청 시 서버는 object key 존재 여부만 검증- 게시글에는
imageObjectKeys만 저장
이 상태에서는 다음이 어렵다.
- 요청 경로에서 동기 압축 비용이 얼마나 드는지 측정할 수 없음
- 이후
동기 압축 -> 비동기 압축전환 시 비교 기준이 약함 - 원본 temp 이미지와 최종 public 이미지가 분리되지 않아 후처리 파이프라인을 설명하기 어려움
따라서 먼저 동기 압축 MVP가 가능한 최소 기반을 만든다.
목표
이번 이슈의 목표는 구조를 크게 뒤집지 않고, 현재 게시글 이미지 업로드 흐름 위에 동기 압축 + 썸네일 생성 + 최종 저장이 가능한 초기 세팅을 추가하는 것이다.
핵심은 아래 3가지다.
- 게시글 이미지를
temp경로에 먼저 업로드하도록 전환 POST /api/posts요청 경로에서 동기 압축을 수행할 수 있는 기반 추가- 이후 2단계에서 같은 압축 로직을 Lambda/SQS 기반 비동기 처리로 옮기기 쉬운 형태로 정리
구현 범위
1. 게시글 이미지 업로드 경로를 temp 기준으로 분리
현재 게시글 이미지 presigned URL은 사실상 최종 공개 경로를 바로 향하고 있다. 이를 temp -> final/public 구조로 바꾼다.
예상 작업:
FileDomain에 게시글 temp/final/thumbnail 경로 개념 추가/api/posts/images/presigned-url는 게시글 원본 업로드 시temp경로로만 발급- 최종 공개 이미지는
public경로에 저장되도록 규칙 정리 - temp 이미지는 추후 lifecycle 정책으로 정리 가능하도록 prefix를 명확히 둠
예상 영향 파일:
src/main/java/com/example/kaboocampostproject/domain/s3/enums/FileDomain.javasrc/main/java/com/example/kaboocampostproject/domain/s3/controller/S3Controller.javasrc/main/java/com/example/kaboocampostproject/domain/s3/service/S3Service.java
2. S3 유틸에 동기 압축용 입출력 기능 추가
지금은 presigned URL 생성, head 조회, delete 중심이다. 동기 압축을 하려면 서버가 temp 이미지를 읽고, 압축 결과를 다시 업로드할 수 있어야 한다.
예상 작업:
- S3에서 원본 이미지를 읽는 메서드 추가
- 압축 결과 바이트를 최종 경로에 업로드하는 메서드 추가
- 필요 시 content-type 지정 가능하게 정리
예상 영향 파일:
src/main/java/com/example/kaboocampostproject/domain/s3/util/S3Util.java
3. 이미지 처리 라이브러리 추가
현재 프로젝트에는 이미지 리사이즈/압축 라이브러리가 없다. 동기 압축 MVP 구현을 위해 최소 의존성을 추가한다.
예상 작업:
build.gradle에 이미지 처리 라이브러리 추가- 1단계에서는 본문 이미지 리사이즈 + 썸네일 생성 + 메타데이터 제거 수준을 목표로 함
예상 영향 파일:
build.gradle
4. PostDocument에 최소 상태 필드 추가
포트폴리오 계획서 기준으로는 복잡한 상태 머신이 아니라 최소 상태 모델만 유지한다.
추가 대상 필드:
imageStatus(PENDING,COMPLETED,FAILED)imageJobIdfailureReasontempImageKeysfinalImageKeysthumbnailKeyscompletedAt
설계 원칙:
- 측정과 상태 확인에 필요한 최소 필드만 추가
- 기존
imageObjectKeys는 초기 호환성을 위해 유지 가능 - 요청 시점은 별도 필드 대신
createdAt활용
예상 영향 파일:
src/main/java/com/example/kaboocampostproject/domain/post/document/PostDocument.java- 필요 시 관련 converter / dto
5. 최소 상태 enum 추가
문자열 하드코딩을 피하기 위해 게시글 이미지 상태 enum을 추가한다.
예상 작업:
PostImageStatusenum 추가- 상태는
PENDING,COMPLETED,FAILED만 사용
예상 영향 파일:
src/main/java/com/example/kaboocampostproject/domain/post/...하위 enum 또는 공용 위치
6. 동기 압축을 담당할 ImageProcessingService 추가
서비스는 과하게 쪼개지 않는다. 이번 단계에서는 ImageProcessingService 하나만 두고, 내부에서 download -> compress -> upload 흐름을 처리한다.
예상 작업:
- temp key 목록을 받아 원본 이미지 다운로드
- 본문 이미지 압축 수행
- 썸네일 생성
- final/public 경로 및 thumbnail 경로 업로드
- 최종 key 목록 반환
설계 원칙:
- 모듈 수를 늘리기보다 1단계 구현 속도와 이해도를 우선
- 다만 2단계에서도 같은 압축 로직을 재사용할 수 있도록 서비스 진입점은 명확히 유지
예상 영향 파일:
- 신규
ImageProcessingService
7. POST /api/posts 생성 흐름에 동기 압축 삽입
현재는 업로드 검증 후 게시글을 바로 저장한다. 이를 동기 압축이 반영되는 흐름으로 바꾼다.
목표 흐름:
- temp image key 검증
- 서버가 temp 이미지 다운로드
- 동기 압축 + 썸네일 생성
- final/public 업로드
- 게시글을
COMPLETED상태로 저장 - 실패 시
FAILED상태 및 failureReason 반영
예상 영향 파일:
src/main/java/com/example/kaboocampostproject/domain/post/service/PostMongoService.javasrc/main/java/com/example/kaboocampostproject/domain/post/converter/PostConverter.java- 관련 DTO/응답 모델
8. 게시글 조회 응답에 최소 상태 노출 검토
2단계 비동기 전환을 고려하면 게시글 상세조회에서 imageStatus를 확인할 수 있어야 한다. 이번 이슈에서 함께 넣을지 여부는 구현 중 판단하되, 최소한 DTO 확장 지점은 열어둔다.
후보 필드:
imageStatusthumbnailKeys
예상 영향 파일:
src/main/java/com/example/kaboocampostproject/domain/post/dto/res/PostDetailResDTO.javasrc/main/java/com/example/kaboocampostproject/domain/post/converter/PostConverter.java
9. 성능 측정을 위한 최소 로깅/메트릭 포인트 추가
포트폴리오 1단계에서 보여줄 수치가 필요하므로 동기 압축 수행 시간과 API 관찰 포인트를 남긴다.
최소 측정 대상:
POST /postsp95- API error rate
- Spring CPU
- 필요 시 내부 참고용 total image processing time
예상 작업:
ImageProcessingService또는PostMongoService에서 처리 시간 로깅- 기존 actuator/prometheus와 연결 가능한 방식으로 남기기
비범위
이번 이슈에서는 아래는 하지 않는다.
- SQS/Lambda 비동기 처리 전환
- Transactional Outbox
- idempotent consumer
- DLQ
- 과도한 서비스 세분화
- 복잡한 상태 머신 (
PROCESSING등 추가 단계)
완료 조건
- 게시글 이미지 presigned URL이
temp경로 기준으로 발급된다 - 서버가 temp 이미지를 읽어 동기 압축 후 최종 이미지와 썸네일을 저장할 수 있다
POST /api/posts가 동기 압축을 수행한 뒤 게시글을 저장한다- Post 문서에 최소 상태 필드가 반영된다
- 이후 2단계에서 동일 압축 로직을 비동기 처리로 옮길 수 있는 진입점이 마련된다
- 포트폴리오 1단계 측정을 위한 최소 관측 포인트가 확보된다
체크리스트
- 게시글 image presigned 경로를 temp prefix 기준으로 분리
- S3Util download/upload 기능 추가
- 이미지 압축 라이브러리 의존성 추가
- Post 최소 상태 필드 추가
- PostImageStatus enum 추가
- ImageProcessingService 추가
-
POST /api/posts동기 압축 흐름 반영 - 필요 시 게시글 상세조회 응답에 imageStatus 반영
- 성능 측정용 최소 로깅/메트릭 포인트 추가
참고
- 계획서:
docs/image-resize-to-portfolio.md - 이 이슈는 포트폴리오 스토리라인의 1단계인
동기 처리 MVP 구현에 해당한다.