feat: 채팅 이미지 업로드 API 구현 (presign/confirm)#88
Conversation
📝 WalkthroughWalkthroughAdds a two-step chat image upload flow with validated request/response DTOs, authenticated REST endpoints, joined-party authorization, S3 presigned upload delegation, upload confirmation, and service-level tests. ChangesChat image upload
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant ChatImageController
participant ChatImageService
participant PartyParticipantRepository
participant ImageStorageService
Client->>ChatImageController: POST /presign
ChatImageController->>ChatImageService: presignUpload(partyId, userId, contentType)
ChatImageService->>PartyParticipantRepository: Check JOINED participation
ChatImageService->>ImageStorageService: issueUploadUrl(CHAT, partyId, contentType)
ImageStorageService-->>Client: Presigned upload URL and key
Client->>ImageStorageService: Upload image
Client->>ChatImageController: POST /confirm
ChatImageController->>ChatImageService: confirmUpload(partyId, userId, key)
ChatImageService->>PartyParticipantRepository: Check JOINED participation
ChatImageService->>ImageStorageService: confirmUpload(key)
ChatImageController-->>Client: Success response
Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/leets/tdd/chat/service/ChatImageService.java`:
- Around line 44-48: Update ChatImageService.confirmUpload to validate the
upload key against ImageCategory.CHAT and the requested party through the
storage contract, then persist or tag a server-verifiable confirmed claim for
that key. Update the WebSocket bare-key IMAGE handling to require and consume
that claim before accepting the image, preserving participant validation and
existing upload validation.
In `@src/test/java/com/leets/tdd/chat/service/ChatImageServiceTest.java`:
- Around line 55-63: Update the ChatImageServiceTest stubbing and verification
of imageStorageService.issueUploadUrl to use eq("image/jpeg") instead of
anyString(), ensuring presignUpload forwards the request content type exactly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: e3633a5b-d21c-4881-87c6-a2784065ca72
📒 Files selected for processing (6)
src/main/java/com/leets/tdd/chat/controller/ChatImageController.javasrc/main/java/com/leets/tdd/chat/dto/ChatImageConfirmRequest.javasrc/main/java/com/leets/tdd/chat/dto/ChatImagePresignRequest.javasrc/main/java/com/leets/tdd/chat/dto/ChatImagePresignResponse.javasrc/main/java/com/leets/tdd/chat/service/ChatImageService.javasrc/test/java/com/leets/tdd/chat/service/ChatImageServiceTest.java
| when(imageStorageService.issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), anyString())) | ||
| .thenReturn(new PresignedUploadResponse(CHAT_KEY, "https://s3.example.com/put", "image/jpeg", 300)); | ||
|
|
||
| ChatImagePresignResponse response = | ||
| chatImageService.presignUpload(PARTY_ID, USER_ID, new ChatImagePresignRequest("image/jpeg")); | ||
|
|
||
| assertThat(response.key()).isEqualTo(CHAT_KEY); | ||
| assertThat(response.uploadUrl()).isEqualTo("https://s3.example.com/put"); | ||
| verify(imageStorageService).issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), anyString()); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the exact content type passed to storage.
Using anyString() allows the test to pass if request.contentType() is accidentally changed or ignored. Use eq("image/jpeg") in both the stub and verification so the forwarding contract is covered.
Proposed fix
- when(imageStorageService.issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), anyString()))
+ when(imageStorageService.issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), eq("image/jpeg")))
...
- verify(imageStorageService).issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), anyString());
+ verify(imageStorageService).issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), eq("image/jpeg"));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| when(imageStorageService.issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), anyString())) | |
| .thenReturn(new PresignedUploadResponse(CHAT_KEY, "https://s3.example.com/put", "image/jpeg", 300)); | |
| ChatImagePresignResponse response = | |
| chatImageService.presignUpload(PARTY_ID, USER_ID, new ChatImagePresignRequest("image/jpeg")); | |
| assertThat(response.key()).isEqualTo(CHAT_KEY); | |
| assertThat(response.uploadUrl()).isEqualTo("https://s3.example.com/put"); | |
| verify(imageStorageService).issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), anyString()); | |
| when(imageStorageService.issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), eq("image/jpeg"))) | |
| .thenReturn(new PresignedUploadResponse(CHAT_KEY, "https://s3.example.com/put", "image/jpeg", 300)); | |
| ChatImagePresignResponse response = | |
| chatImageService.presignUpload(PARTY_ID, USER_ID, new ChatImagePresignRequest("image/jpeg")); | |
| assertThat(response.key()).isEqualTo(CHAT_KEY); | |
| assertThat(response.uploadUrl()).isEqualTo("https://s3.example.com/put"); | |
| verify(imageStorageService).issueUploadUrl(eq(ImageCategory.CHAT), eq(PARTY_ID), eq("image/jpeg")); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/test/java/com/leets/tdd/chat/service/ChatImageServiceTest.java` around
lines 55 - 63, Update the ChatImageServiceTest stubbing and verification of
imageStorageService.issueUploadUrl to use eq("image/jpeg") instead of
anyString(), ensuring presignUpload forwards the request content type exactly.
작업 내용
채팅 메시지 이미지 첨부(FR-CHAT-05)를 위한 presign/confirm API 구현. (#87)
변경 사항
이슈(#87) 계획 대비 변경점
설계
남은 작업
Connected #87
Summary by CodeRabbit