Skip to content

미디어 Presigned URL 업로드 및 삭제 API 구현 - #20

Merged
cfcromn merged 6 commits into
developfrom
feature/19-media-presigned-upload
Aug 5, 2026
Merged

미디어 Presigned URL 업로드 및 삭제 API 구현#20
cfcromn merged 6 commits into
developfrom
feature/19-media-presigned-upload

Conversation

@cfcromn

@cfcromn cfcromn commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

✨ 작업 내용

  • 비공개 S3 버킷에 직접 업로드할 수 있는 Presigned PUT URL 발급 API를 추가하였습니다.
  • 업로드 완료 등록 시 소유권, MIME, 크기를 재검증하고 pending/ 객체를 영구 경로로 승격하도록 구현하였습니다.
  • 동일 uploadKey의 재시도와 동시 요청에서도 중복 Media가 생성되지 않도록 멱등성을 보장하였습니다.
  • 업로더가 소유한 미연결 미디어만 삭제할 수 있도록 삭제 API를 추가하였습니다.
  • MediaStorage 포트와 AWS S3 어댑터, Flyway V4 마이그레이션을 추가하였습니다.
  • MockK 서비스 테스트와 MockMvc Controller 테스트를 추가하고 Notion API 명세를 갱신하였습니다.

🔍 리뷰 시 참고사항

  • tbl_media.uploader_id는 기존 캡슐 작성자로 backfill한 뒤 NOT NULL로 전환하였습니다.
  • 배포된 V2 마이그레이션은 수정하지 않았으며, 기존 media_url 컬럼은 2단계 삭제를 위해 남겨두고 NOT NULL 제약만 해제하였습니다.
  • S3 버킷은 private이어야 하며 브라우저 PUT CORS와 pending/ 1일 만료 Lifecycle 설정이 필요합니다.
  • 미디어 테스트 15개는 모두 통과하였습니다. 전체 테스트 99개 중 기존 Testcontainers 테스트 2개는 로컬 Docker 데몬 부재로 초기화되지 않았고 나머지 97개는 통과하였습니다.

✅ 체크리스트

  • 문서(README, .env.example 등) 변경이 필요한 경우 작성 또는 수정했나요?
  • 작업한 코드가 정상적으로 동작하는 것을 직접 확인했나요?
  • 필요한 경우 테스트 코드를 작성하거나 수정했나요?
  • Merge 대상 브랜치를 올바르게 설정했나요?
  • PR에 관련 없는 작업이 포함되지 않았나요?
  • 적절한 라벨과 리뷰어를 설정했나요?

📎 관련 이슈(선택)

@cfcromn cfcromn added ✅ Test Test관련사항 ✨ Feature 신규 기능 labels Aug 1, 2026
@cfcromn
cfcromn requested a review from hej090224 August 1, 2026 05:51
@cfcromn cfcromn self-assigned this Aug 1, 2026

@hej090224 hej090224 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 잘 구성된 구현입니다. presigned URL 발급 → 서버 재검증 → 승격이라는 흐름 자체가 CLAUDE.md의 "클라이언트를 신뢰하지 않는다" 원칙과 잘 맞고, insertUnattachedON CONFLICT DO NOTHING으로 멱등성을 확보한 아이디어도 좋습니다. 인라인으로 몇 가지 개선 여지와 잠재적 버그 가능성을 남깁니다.

추가로 두 가지는 파일 라인에 걸기 애매해서 여기 적습니다.

  1. 마이그레이션 버전 충돌 우려: 이 PR의 V4__support_pending_media_uploads.sql과 별도로 열려있는 Friend 도메인 PR(#22)도 V4__...sql을 추가합니다. 두 PR이 모두 머지되면 Flyway 버전 번호가 충돌하니, 나중에 머지되는 쪽에서 V5로 재번호가 필요합니다. 병합 순서 조율이 필요해 보입니다.
  2. 테스트 커버리지: CompleteMediaUploadService.execute()의 컨텐츠 타입/사이즈 서버 재검증 분기(43~47번 줄, storedObject.contentType/contentLength 체크)를 직접 검증하는 테스트가 없습니다. 클라이언트가 선언한 값과 실제 업로드된 객체가 다른 경우를 막는 핵심 방어 로직이라 커버리지를 추가하면 좋겠습니다.

(참고로 V4__support_pending_media_uploads.sqlALTER COLUMN uploader_id SET NOT NULL은 PostgreSQL에서 기존 CHECK 제약 없이는 테이블 풀스캔 + ACCESS EXCLUSIVE 락을 유발할 수 있습니다. 지금 단계에서는 데이터량이 적어 문제없겠지만, blue-green 무중단 배포 원칙상 나중에 큰 테이블에 비슷한 마이그레이션을 쓸 땐 유의가 필요합니다.)

@cfcromn
cfcromn merged commit 6574884 into develop Aug 5, 2026
2 checks passed
@cfcromn
cfcromn deleted the feature/19-media-presigned-upload branch August 5, 2026 10:07
hej090224 added a commit that referenced this pull request Aug 5, 2026
develop merged PR #20's V4__support_pending_media_uploads.sql after this
branch's V4__add_friend_request_indexes_and_pending_pair_constraint.sql was
already written. Renumbering to V5 to avoid two migrations claiming version 4,
which Flyway rejects (this is what broke CI on the merge commit).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 신규 기능 ✅ Test Test관련사항

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants