Skip to content

feat(configuration): S3 및 files 테이블 어댑터와 유스케이스 구현 #26 - #57

Open
tlgms wants to merge 4 commits into
feat(document)-파일-도메인-모델-#26from
feat(document)-파일-저장소-어댑터-#26

Hidden character warning

The head ref may contain hidden characters: "feat(document)-\ud30c\uc77c-\uc800\uc7a5\uc18c-\uc5b4\ub311\ud130-#26"
Open

feat(configuration): S3 및 files 테이블 어댑터와 유스케이스 구현 #26#57
tlgms wants to merge 4 commits into
feat(document)-파일-도메인-모델-#26from
feat(document)-파일-저장소-어댑터-#26

Conversation

@tlgms

@tlgms tlgms commented Jul 27, 2026

Copy link
Copy Markdown

스택 PR 2/4 — base: feat(document)-파일-도메인-모델-#26
PR 1이 먼저 머지되어야 합니다. 머지 후 base가 develop으로 자동 전환됩니다.

Summary

  • StoragePort를 AWS S3로, FileDocumentRepository를 JPA로 구현합니다.
  • 두 포트를 조합하는 FileDocumentService 유스케이스를 추가합니다.

Related Issue

Scope

  • In scope: configuration-adapter-out, configuration-application, kotlin.MODULE.bazel
  • Out of scope: REST / gRPC 진입점, 버킷 생성·IAM 정책, 마이그레이션 도구 도입

Implementation

바이너리는 S3에, 메타데이터는 DB(files)에 둡니다. 응답으로 바이너리를 스트리밍하지 않고 presigned URL을 반환해 서버 부하를 줄입니다.

어댑터

  • S3StorageAdapter — 업로드 시 SHA-256 체크섬 수신, presigned URL 발급, 존재 확인, 삭제
  • S3ConfigS3Client / S3Presigner 빈. 자격증명은 기본 provider chain
  • FileDocumentJpaEntity / JpaRepository / PersistenceAdapter — ERD files 스키마 대응, object_key에 유니크 제약
  • SdkExceptionSTORAGE_UPLOAD_FAILED / PRESIGN_FAILED 도메인 예외로 변환해 AWS 타입이 어댑터 밖으로 새지 않게 합니다

유스케이스 — 순서가 핵심입니다

S3 업로드는 DB 트랜잭션에 참여하지 않습니다. 순서를 잘못 잡으면 검증 실패인데 S3를 호출하거나, 메타데이터 없이 객체만 남습니다.

1. 검증(형식·용량)  → 실패 시 S3 호출 없이 400/413
2. S3 업로드        → 실패 시 502, DB 미변경
3. 메타데이터 저장   → 실패 시 업로드된 객체를 보상 삭제

보상 삭제가 또 실패하면 로깅만 하고 원래 예외를 덮지 않습니다. 삭제 실패로 진짜 원인을 가리지 않기 위해서입니다.

Testing

  • Unit tests — 이 PR 범위에는 없습니다 (후속 이슈)
  • Integration tests — 후속 이슈
  • Manual verification
bazel build //systems/configuration/...
bazel test  //systems/configuration/...

컴파일과 기존 테스트 통과만 확인했습니다. S3StorageAdapter실제 S3에 대해 검증되지 않았습니다.

Deployment Notes

  • Feature flag: 없음
  • Migration required: files 테이블이 필요합니다. ddl-auto: validate이므로 없으면 기동 실패합니다. DDL은 PR 4에 포함되어 있습니다
  • Rollout considerations: S3_BUCKET, AWS_REGION 환경변수 주입 필요 (PR 4)

Checklist

  • Matches product/tech requirements
  • Backward compatibility considered
  • Docs updated if applicable

리뷰 시 봐주셨으면 하는 것

  1. RequestBody.fromInputStream + checksumAlgorithm(SHA256) 조합 — 스트리밍 체크섬이 실제로 동작하는지 목으로는 확인이 안 됩니다. 통합 테스트를 후속 이슈로 잡아두었습니다. 체크섬이 null이면 eTag로 폴백합니다.
  2. AWS SDK 버전 2.31.0 — One-Version Rule에 따라 kotlin.MODULE.bazel에만 기재했습니다. 팀에서 쓰는 버전이 따로 있으면 알려주세요.
  3. 보상 삭제까지 실패하면 고아 객체가 남습니다. 주기적 정리는 이 PR 범위 밖입니다.

tlgms and others added 4 commits July 27, 2026 20:46
One-Version Rule에 따라 kotlin.MODULE.bazel에 버전을 고정하고
configuration-adapter-out에서만 S3를 참조한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ERD의 files 스키마에 대응하는 JPA 엔티티와 FileDocumentRepository
아웃바운드 포트 구현을 추가한다. object_key에 유니크 제약을 둔다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
StoragePort를 AWS SDK v2로 구현한다. 업로드 시 SHA-256 체크섬을 받아
files 메타데이터에 남기고, 다운로드는 presigned URL로 발급한다.

SdkException을 STORAGE_UPLOAD_FAILED / PRESIGN_FAILED 도메인 예외로
변환해 어댑터 밖으로 AWS 타입이 새지 않게 한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FileDocumentService가 UploadFileUseCase, IssueDownloadUrlUseCase,
ReadFileUseCase를 구현한다.

검증(형식/용량) → S3 업로드 → 메타데이터 저장 순서를 지키고,
메타데이터 저장이 실패하면 업로드된 객체를 보상 삭제한다.
보상 삭제 실패는 로깅만 하고 원래 예외를 덮지 않는다.

파일명은 API마다 결정 방식이 달라 커맨드의 fileName을 필수로 바꾸고
컨트롤러가 결정하도록 한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • ready-for-review
🚫 Excluded labels (none allowed) (2)
  • wip
  • do-not-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 650635ce-b423-4f22-9398-ba941aaa0601

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat(document)-파일-저장소-어댑터-#26
  • 🛠️ cleanup stale imports
  • 🛠️ harden error messages
  • 🛠️ test clarity pass

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tlgms
tlgms requested review from kusuri12-09 and wlyoon921 July 27, 2026 13:58
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.

1 participant