refactor: 관리자 대학 이미지 업로드 경로 식별자 개선#782
Conversation
- 관리자 대학 생성/수정 API에서 multipart로 대학 정보와 이미지 파일을 함께 받도록 변경 - 이미지 URL을 요청 DTO에서 제거하고 서버에서 S3 업로드 결과를 저장하도록 변경 - 영문명 slug와 한글명 hash를 조합해 중복 영문명 간 S3 경로 충돌을 방지 - 업로드 또는 DB 저장 실패 시 새로 업로드된 이미지가 남지 않도록 보상 삭제 처리
- 대학 생성/수정 시 이미지 업로드 URL 저장과 기존 이미지 유지 동작 검증 - 한글명 기반 S3 경로 식별자와 중복 영문명 충돌 방지 검증 - 업로드 실패 보상 삭제와 삭제용 key 사용 여부 검증
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b029f6fae4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @RequestPart("logoFile") MultipartFile logoFile, | ||
| @RequestPart("backgroundFile") MultipartFile backgroundFile |
There was a problem hiding this comment.
Raise multipart request limit for paired image uploads
This create endpoint now requires logoFile and backgroundFile in the same multipart request, but application.yml still caps spring.servlet.multipart.max-request-size at 10MB while each individual file is allowed up to 10MB. A logo and background that are each valid on their own, e.g. two ~6MB images, will be rejected by the servlet container before reaching this controller, so admins cannot create a university with two otherwise acceptable images unless the aggregate request limit is raised or uploads remain separate.
Useful? React with 👍 / 👎.
| if (uploadedFile == null) { | ||
| return; | ||
| } | ||
| deleteFile(uploadedFile.deletionKey()); |
There was a problem hiding this comment.
Delete the resized object during compensation
For images at or above the resize threshold, uploadFile stores deletionKey as original/... but returns fileUrl as resize/...webp; this compensation path deletes only the original key. If a later background upload or DB flush fails after the resize Lambda has already produced the resized logo/background, AdminHostUniversityService.deleteUploadedImages leaves the resize/... object orphaned even though the university was not saved. Delete both keys when they differ, or otherwise remove the generated resize key too.
Useful? React with 👍 / 👎.
관련 이슈
작업 내용
관리자 대학 이미지 업로드를 대학 생성/수정 API에 통합
multipart/form-data로 대학 정보 JSON(request)과 로고/배경 이미지 파일을 함께 받도록 변경했습니다.multipart/form-data로 변경하고, 로고/배경 이미지 파일은 선택 입력으로 처리했습니다./file/admin/university/logo,/file/admin/university/background)는 제거했습니다.이유
이미지 URL 요청 필드 제거
AdminHostUniversityCreateRequest,AdminHostUniversityUpdateRequest에서logoImageUrl,backgroundImageUrl을 제거했습니다.HostUniversity이미지 필드에 저장하도록 변경했습니다.이유
대학별 S3 경로 식별자 개선
UploadDirectoryName.fromUniversityNames(englishName, koreanName)을 추가했습니다.이유
HostUniversity.englishName은 unique 제약이 없어 서로 다른 대학이 같은 영문명을 가질 수 있습니다.업로드 실패 보상 삭제 처리
warn로그만 남기고 원래 예외를 유지했습니다.이유
S3 삭제 API 캡슐화
S3Service.deleteFile(String)은 내부 구현으로 유지하고, 외부에서는deleteUploadedFile(UploadedFileUrlResponse)를 사용하도록 변경했습니다.UploadedFileUrlResponse에 내부 삭제용deletionKey를 추가하고, API 응답에는 노출되지 않도록@JsonIgnore를 적용했습니다.이유
S3Service내부로 캡슐화했습니다.테스트 보강
deleteUploadedFile이fileUrl이 아니라deletionKey로 삭제 요청을 보내는지 검증했습니다.이유
특이 사항
multipart/form-data로 변경됩니다.request,logoFile,backgroundFilepart가 필요합니다.requestpart가 필요하고,logoFile,backgroundFilepart는 선택입니다.리뷰 요구사항 (선택)
AdminHostUniversityService가 S3 업로드까지 담당하도록 변경한 결합도가 현재 유스케이스 기준에서 적절한지 확인 부탁드립니다.