ID: key_26_22_05_25_P3_3_1 Created date: 5월 25 2026 월요일

연관 문서


개요

이슈 첨부 파일 업로드 API를 구현한다. 스토리지는 AWS S3 또는 MinIO를 사용한다.

  • 예상 소요: 3~4일
  • 선행 조건: 스토리지 결정 (AWS S3 / GCS / MinIO)
  • 완료 기준: 파일 업로드 → S3 저장 → 다운로드 URL 반환 동작 확인

Claude Code 작업 수행서

작업 지시

CIRA 서버에 파일 첨부 API를 구현해줘.

[스토리지 선택]
- [AWS S3 / MinIO 중 결정값]
- Bucket 이름: cira-attachments
- Region: (결정값)

[수행 작업]

1. 의존성 추가
   - AWS SDK v2: software.amazon.awssdk:s3
   - 또는 MinIO: io.minio:minio

2. 스토리지 설정
   파일: application.yml
   cloud:
     aws:
       s3.bucket: cira-attachments
       credentials.access-key: (placeholder)
       credentials.secret-key: (placeholder)
       region.static: ap-northeast-2

3. StorageService 구현
   파일: src/main/java/.../common/storage/StorageService.java
   - upload(MultipartFile file, String path): String (저장된 S3 key)
   - generatePresignedUrl(String s3Key): String (15분 유효 URL)
   - delete(String s3Key): void
   파일 경로 패턴: attachments/{projectId}/{issueId}/{uuid}_{originalFileName}

4. 첨부 파일 API
   POST   /api/v1/issues/{issueId}/attachments
   - multipart/form-data 수신
   - 파일 크기 제한: 50MB
   - 허용 MIME 타입: image/*, application/pdf, text/*, application/zip 등
   - S3 업로드 → attachments 테이블 INSERT
   - Response: AttachmentResponse (id, fileName, fileSize, mimeType, uploadedAt, downloadUrl)

   GET    /api/v1/issues/{issueId}/attachments
   - attachments 테이블 조회
   - 각 파일에 Presigned URL 포함

   GET    /api/v1/attachments/{attachmentId}/download
   - Presigned URL 생성 후 302 Redirect

   DELETE /api/v1/attachments/{attachmentId}
   - S3 파일 삭제
   - attachments 테이블 Soft Delete

5. 보안 처리
   - 파일명 sanitize (경로 traversal 방지)
   - 업로드자 또는 프로젝트 Admin만 삭제 가능
   - Presigned URL TTL: 15분

6. issue_logs에 첨부 기록
   - 파일 추가/삭제 시 이슈 이력에 기록

[준수 사항]
- 비동기 업로드 고려 (대용량 파일)
- 업로드 실패 시 S3 임시 파일 정리 (트랜잭션 주의)

완료 기준

항목기준
파일 업로드S3 저장 + DB 기록
다운로드 URLPresigned URL 정상 동작
파일 삭제S3 + DB 동시 처리
파일 크기/타입 검증초과/비허용 시 400 에러