Skip to content

refactor: 관리자 대학 이미지 업로드 경로 식별자 개선#782

Draft
lsy1307 wants to merge 2 commits into
developfrom
refactor/774-admin-university-image-path-identifier
Draft

refactor: 관리자 대학 이미지 업로드 경로 식별자 개선#782
lsy1307 wants to merge 2 commits into
developfrom
refactor/774-admin-university-image-path-identifier

Conversation

@lsy1307

@lsy1307 lsy1307 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

작업 내용

관리자 대학 이미지 업로드를 대학 생성/수정 API에 통합

  • 관리자 대학 생성 API가 multipart/form-data로 대학 정보 JSON(request)과 로고/배경 이미지 파일을 함께 받도록 변경했습니다.
  • 관리자 대학 수정 API도 multipart/form-data로 변경하고, 로고/배경 이미지 파일은 선택 입력으로 처리했습니다.
  • 기존 분리형 관리자 대학 이미지 업로드 API(/file/admin/university/logo, /file/admin/university/background)는 제거했습니다.

이유

  • 이미지 업로드 API와 대학 CRUD API가 분리되어 있으면 프론트에서 호출 순서를 관리해야 하고, 업로드 성공 후 대학 생성/수정 실패 시 S3 파일이 남을 수 있습니다.
  • 대학 이미지 업로드는 대학 생성/수정 유스케이스에 종속된 작업이므로, 서버에서 하나의 작업 흐름으로 관리하는 편이 실패 처리와 데이터 정합성 측면에서 안전합니다.

이미지 URL 요청 필드 제거

  • AdminHostUniversityCreateRequest, AdminHostUniversityUpdateRequest에서 logoImageUrl, backgroundImageUrl을 제거했습니다.
  • 서버가 S3 업로드 결과로 받은 URL을 HostUniversity 이미지 필드에 저장하도록 변경했습니다.

이유

  • 클라이언트가 임의 URL을 전달하는 구조에서는 업로드 실패, 비이미지 파일 URL 저장, 잘못된 경로 저장을 서버가 충분히 제어하기 어렵습니다.
  • 이미지 파일 검증과 URL 생성 책임을 서버로 모아 관리자 대학 이미지 필드의 무결성을 높였습니다.

대학별 S3 경로 식별자 개선

  • UploadDirectoryName.fromUniversityNames(englishName, koreanName)을 추가했습니다.
  • 디렉토리 prefix는 영문명을 slug로 변환하고, suffix hash는 unique 제약이 있는 한글명 기준으로 생성하도록 변경했습니다.

이유

  • HostUniversity.englishName은 unique 제약이 없어 서로 다른 대학이 같은 영문명을 가질 수 있습니다.
  • 영문명 정규화는 공백/특수문자 제거 등 손실적 변환이 포함되어 같은 slug로 충돌할 수 있습니다.
  • 한글명은 unique 제약이 있으므로, 같은 영문명이어도 한글명이 다르면 서로 다른 S3 경로를 만들 수 있습니다.

업로드 실패 보상 삭제 처리

  • 대학 생성/수정 중 S3 업로드 또는 DB 저장이 실패하면, 이미 업로드된 새 이미지를 삭제하도록 보상 로직을 추가했습니다.
  • 로고 업로드 성공 후 배경 업로드가 실패하는 경우에도 로고 파일이 남지 않도록 업로드 단계 전체를 보상 삭제 범위에 포함했습니다.
  • 보상 삭제 자체가 실패해도 원래 실패 원인이 덮이지 않도록 warn 로그만 남기고 원래 예외를 유지했습니다.

이유

  • S3는 DB 트랜잭션에 포함되지 않기 때문에 DB rollback만으로 업로드된 파일을 되돌릴 수 없습니다.
  • 중간 실패 시 orphan 파일이 남지 않도록 서버에서 보상 삭제를 수행해야 합니다.
  • 보상 삭제 실패가 원래 예외를 덮으면 실제 원인 파악이 어려워지므로 원래 예외를 보존했습니다.

S3 삭제 API 캡슐화

  • S3Service.deleteFile(String)은 내부 구현으로 유지하고, 외부에서는 deleteUploadedFile(UploadedFileUrlResponse)를 사용하도록 변경했습니다.
  • UploadedFileUrlResponse에 내부 삭제용 deletionKey를 추가하고, API 응답에는 노출되지 않도록 @JsonIgnore를 적용했습니다.

이유

  • 리사이즈 대상 이미지는 클라이언트/DB에 저장되는 반환 URL과 실제 업로드 key가 다를 수 있습니다.
  • 삭제 호출부가 S3 key 정책을 직접 알지 않도록 삭제 책임을 S3Service 내부로 캡슐화했습니다.

테스트 보강

  • 관리자 대학 생성/수정 시 이미지 업로드 URL 저장 동작을 검증했습니다.
  • 수정 시 이미지 파일을 전달하지 않으면 기존 이미지 URL을 유지하는지 검증했습니다.
  • 같은 영문명이어도 한글명이 다르면 서로 다른 S3 경로가 생성되는지 검증했습니다.
  • 배경 이미지 업로드 실패 시 이미 업로드된 로고 이미지가 보상 삭제되는지 검증했습니다.
  • 보상 삭제가 실패해도 원래 예외가 유지되는지 검증했습니다.
  • deleteUploadedFilefileUrl이 아니라 deletionKey로 삭제 요청을 보내는지 검증했습니다.

이유

  • 이번 변경은 API 요청 형식, S3 경로 생성, 실패 보상 로직이 함께 바뀌므로 정상 흐름뿐 아니라 중간 실패 흐름까지 회귀 테스트가 필요합니다.

특이 사항

  • 관리자 대학 생성/수정 API 요청 형식이 JSON body에서 multipart/form-data로 변경됩니다.
  • 생성 요청은 request, logoFile, backgroundFile part가 필요합니다.
  • 수정 요청은 request part가 필요하고, logoFile, backgroundFile part는 선택입니다.
  • 기존 이미지 교체 성공 후 old image 삭제는 이번 PR 범위에 포함하지 않았습니다. 커밋 성공 이후 삭제되어야 하므로 별도 후속 작업으로 다루는 것이 안전합니다.
  • S3 업로드가 비동기로 처리되는 구조상, 실제 S3 반영 실패까지 DB 트랜잭션과 완전히 묶는 문제는 별도 개선 포인트로 남아 있습니다.

리뷰 요구사항 (선택)

  • AdminHostUniversityService가 S3 업로드까지 담당하도록 변경한 결합도가 현재 유스케이스 기준에서 적절한지 확인 부탁드립니다.
  • 한글명 unique 제약을 기반으로 S3 경로 hash suffix를 만드는 방향이 도메인 정책과 맞는지 확인 부탁드립니다.
  • 업로드 실패 보상 삭제 범위와 예외 보존 방식이 충분한지 확인 부탁드립니다.

lsy1307 added 2 commits June 21, 2026 09:57
- 관리자 대학 생성/수정 API에서 multipart로 대학 정보와 이미지 파일을 함께 받도록 변경

- 이미지 URL을 요청 DTO에서 제거하고 서버에서 S3 업로드 결과를 저장하도록 변경

- 영문명 slug와 한글명 hash를 조합해 중복 영문명 간 S3 경로 충돌을 방지

- 업로드 또는 DB 저장 실패 시 새로 업로드된 이미지가 남지 않도록 보상 삭제 처리
- 대학 생성/수정 시 이미지 업로드 URL 저장과 기존 이미지 유지 동작 검증

- 한글명 기반 S3 경로 식별자와 중복 영문명 충돌 방지 검증

- 업로드 실패 보상 삭제와 삭제용 key 사용 여부 검증
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3b2379e8-52e7-4cee-8d84-994e07081150

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:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/774-admin-university-image-path-identifier

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 and usage tips.

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