feat: implement AttachmentController and record-based file management#129
feat: implement AttachmentController and record-based file management#129johanbriger merged 6 commits intomainfrom
Conversation
📝 WalkthroughWalkthroughAdded an Attachment REST controller with upload/list/download/delete endpoints, service additions for listing attachments by medical record and S3 key filename sanitization, a small repository parameter rename, and a global handler for jakarta.validation.ConstraintViolationException. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller as "AttachmentController"
participant Auth as "Authentication (User)"
participant Service as "AttachmentService"
participant MRRepo as "MedicalRecordRepository"
participant AttachRepo as "AttachmentRepository"
participant FileStorage as "FileStorageService (S3)"
Client->>Controller: POST /api/attachments/record/{recordId} (multipart file, description)
Controller->>Auth: resolve current User
Controller->>Service: uploadAttachment(User, recordId, file, description)
Service->>MRRepo: findById(recordId)
MRRepo-->>Service: MedicalRecord
Service->>FileStorage: upload(s3Key (uses sanitizedName), fileStream, metadata)
FileStorage-->>Service: upload result
Service->>AttachRepo: save(Attachment entity)
AttachRepo-->>Service: saved Attachment
Service-->>Controller: AttachmentResponse
Controller-->>Client: 201 Created + body
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 the current code and only fix it if needed.
Inline comments:
In `@src/main/java/org/example/vet1177/controller/AttachmentController.java`:
- Around line 33-45: The controller currently lets IOException bubble out from
uploadAttachment in AttachmentController, which causes it to be handled as a
generic 500; either catch IOException inside uploadAttachment (around the call
to attachmentService.uploadAttachment) and return a descriptive ResponseEntity
(e.g., 400 Bad Request with a message like "Invalid or corrupted upload" or 502
for storage backend issues) or translate the IOException into a domain-specific
runtime exception (e.g., AttachmentStorageException) and throw that so
GlobalExceptionHandler can map it; alternatively add an
`@ExceptionHandler`(IOException.class) to GlobalExceptionHandler to return a clear
status and payload for IO failures—use the method name uploadAttachment, DTOs
AttachmentRequest/AttachmentResponse, and the attachmentService call to locate
where to implement the try/catch or exception translation.
In `@src/main/java/org/example/vet1177/services/AttachmentService.java`:
- Around line 167-176: The method getAttachmentsByRecord currently loads the
MedicalRecord via medicalRecordRepository.findById(recordId) but does not
enforce any authorization; before returning the attachments from
attachmentRepository.findByMedicalRecordId(recordId) you must perform the same
permission check used elsewhere (either call
medicalRecordPolicy.canView(currentUser, record) or, if you prefer
AttachmentPolicy, add and call an overloaded attachmentPolicy.canDownload(User,
MedicalRecord) or similar) and throw an appropriate access denied exception when
the check fails; ensure you inject/use medicalRecordPolicy or attachmentPolicy
in AttachmentService and run the check right after fetching the MedicalRecord
and before mapping/returning attachments.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cf9a4ebc-7a41-4df4-9490-ea751c276fb8
📒 Files selected for processing (3)
src/main/java/org/example/vet1177/controller/AttachmentController.javasrc/main/java/org/example/vet1177/repository/AttachmentRepository.javasrc/main/java/org/example/vet1177/services/AttachmentService.java
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/org/example/vet1177/controller/AttachmentController.java`:
- Around line 33-37: The controller currently declares
`@RequestPart`("description") as a required parameter, bypassing the optional
nature and `@Size`(max=500) validation on AttachmentRequest.description; update
the AttachmentController method to accept the description as optional (e.g.,
`@RequestPart`(name="description", required=false) or nullable String) and
explicitly apply the DTO validation (use a BindingResult/Validator or construct
an AttachmentRequest and call javax.validation.Validator) so the
AttachmentRequest.description field's `@Size`(max=500) constraint is enforced
before proceeding; locate the controller method in AttachmentController and the
AttachmentRequest class to implement these changes.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e4b63545-f81f-40ae-b284-ccec549088ca
📒 Files selected for processing (2)
src/main/java/org/example/vet1177/controller/AttachmentController.javasrc/main/java/org/example/vet1177/services/AttachmentService.java
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/org/example/vet1177/services/AttachmentService.java
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/org/example/vet1177/controller/AttachmentController.java`:
- Around line 44-47: The controller currently throws
ConstraintViolationException from AttachmentController when
validator.validate(request) fails, which is not handled by
GlobalExceptionHandler and yields HTTP 500; fix by either adding a dedicated
handler for ConstraintViolationException in GlobalExceptionHandler (create a
method annotated with `@ExceptionHandler`(ConstraintViolationException.class) and
`@ResponseStatus`(HttpStatus.BAD_REQUEST) that converts
ex.getConstraintViolations() into your ErrorResponse structure and logs the
details) or modify AttachmentController to catch ConstraintViolationException
and rethrow a handled exception type (e.g., BusinessRuleException with
appropriate message/body) so GlobalExceptionHandler returns HTTP 400; reference
the symbols ConstraintViolationException, AttachmentController,
validator.validate(request), GlobalExceptionHandler, and ErrorResponse when
implementing the change.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dd368f49-0005-43a7-9ea1-b36d182ae3e3
📒 Files selected for processing (1)
src/main/java/org/example/vet1177/controller/AttachmentController.java
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/main/java/org/example/vet1177/exception/GlobalExceptionHandler.java (2)
96-100: Keep error-message language consistent across handlers.Line 98 returns
"Valideringsfel"while the rest of this class uses English messages. Standardizing this improves API consistency for clients.Suggested small cleanup
ErrorResponse error = new ErrorResponse( HttpStatus.BAD_REQUEST.value(), - "Valideringsfel", - validationErrors // <--- Nu matchar vi Map<String, List<String>> + "Validation failed", + validationErrors );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/vet1177/exception/GlobalExceptionHandler.java` around lines 96 - 100, In GlobalExceptionHandler, the ErrorResponse created in the validation handler uses the Swedish string "Valideringsfel"; change this to an English message consistent with the rest of the class (e.g., "Validation error" or "Validation failed") so ErrorResponse(...) uses the same language as other handlers; update the message passed where ErrorResponse is constructed (around the validationErrors map creation) to match existing English wording used elsewhere in GlobalExceptionHandler.
83-103: Add warning logging for constraint violations.This handler is the only validation path without a log entry, which makes troubleshooting harder compared to the other handlers. Add a
log.warn(...)before returning.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/vet1177/exception/GlobalExceptionHandler.java` around lines 83 - 103, Add a warning log in GlobalExceptionHandler.handleConstraintViolation to mirror other handlers: before creating and returning the ResponseEntity, call log.warn with a concise message that includes details about the ConstraintViolationException (e.g., ex.getMessage() or a summary like validationErrors) so you record the fact of a validation failure and relevant context; ensure you reference the same validationErrors map or ex when composing the log message and that the class has a logger instance (e.g., log) available.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/main/java/org/example/vet1177/exception/GlobalExceptionHandler.java`:
- Around line 96-100: In GlobalExceptionHandler, the ErrorResponse created in
the validation handler uses the Swedish string "Valideringsfel"; change this to
an English message consistent with the rest of the class (e.g., "Validation
error" or "Validation failed") so ErrorResponse(...) uses the same language as
other handlers; update the message passed where ErrorResponse is constructed
(around the validationErrors map creation) to match existing English wording
used elsewhere in GlobalExceptionHandler.
- Around line 83-103: Add a warning log in
GlobalExceptionHandler.handleConstraintViolation to mirror other handlers:
before creating and returning the ResponseEntity, call log.warn with a concise
message that includes details about the ConstraintViolationException (e.g.,
ex.getMessage() or a summary like validationErrors) so you record the fact of a
validation failure and relevant context; ensure you reference the same
validationErrors map or ex when composing the log message and that the class has
a logger instance (e.g., log) available.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c3898cd7-3577-48ee-ab40-5f15f971ada9
📒 Files selected for processing (1)
src/main/java/org/example/vet1177/exception/GlobalExceptionHandler.java
Summary by CodeRabbit
New Features
Bug Fixes / Improvements