Skip to content

Conversation

@NCookies
Copy link
Collaborator

@NCookies NCookies commented Dec 15, 2025

작업 내용

  • 회원 정보 수정 API(PUT /users) 호출 시 Swagger에서 발생하는 Content-Type 에러 해결
  • 프로필 이미지 변경 시 기존 이미지가 S3에서 정상적으로 삭제되지 않는 로직 오류 수정
  • S3 파일 삭제 시 파일명 인코딩 및 Null 처리 안정성 강화

변경 사항

  • UserController
    • @Operation 어노테이션에 requestBodyencoding 설정을 추가하여, Multipart 요청 시 request 파트가 application/json으로 전송되도록 명시
  • UserService
    • modifyUserInfo 메서드 내 로직 순서 변경: 엔티티가 업데이트되기 전에 oldImageUrl을 미리 백업하여, 변경 전 이미지가 삭제되도록 수정
  • S3Uploader
    • delete() 메서드에 URLDecoder.decode() 추가 (특수문자 포함된 파일명 처리)
    • 이미지 URL 유효성 검사에 StringUtils.hasText() 도입 (Null 및 빈 문자열 "" 방지)

트러블 슈팅

  • Swagger Content-Type 문제

    • 문제: Swagger UI에서 요청 시 DTO 파트가 application/octet-stream으로 전송되어 HttpMediaTypeNotSupportedException 발생
    • 해결: 컨트롤러 메서드 상단 @Operation 설정을 통해 content-type: application/json을 강제하도록 수정
  • S3 이미지 삭제 실패 (인코딩)

    • 문제: 파일명에 공백이나 특수문자가 포함된 경우(예: %20), S3 키값과 불일치하여 삭제되지 않음
    • 해결: URLDecoder를 사용하여 파일명을 UTF-8로 디코딩한 후 deleteObject 요청
  • 빈 문자열 에러

    • 문제: 기존 프로필 이미지가 없는 경우 DB에 ""(빈 문자열)로 저장되어 있어, if (url != null) 조건을 통과해 삭제 로직 수행 중 에러 발생
    • 해결: StringUtils.hasText()를 사용하여 빈 문자열까지 안전하게 필터링

참고 사항

  • Swagger UI 및 Postman에서 파일 업로드/수정 정상 동작 확인 완료
  • S3 버킷 내 실제 파일 삭제/생성 확인 완료

코드 리뷰 전 확인 체크리스트

  •   불필요한 콘솔 로그, 주석 제거
  •   커밋 메시지 컨벤션 준수 (type : )
  •   기능 정상 동작 확인

Summary by CodeRabbit

릴리스 노트

  • 버그 수정

    • 프로필 이미지 삭제 로직을 개선하여 올바른 파일이 삭제되도록 수정했습니다.
    • 파일명 인코딩 처리를 추가하여 이미지 삭제 기능의 안정성을 높였습니다.
  • 문서화

    • API 문서에 로컬 서버 옵션을 추가했습니다.
    • 사용자 정보 수정 엔드포인트의 API 문서를 개선했습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@NCookies NCookies self-assigned this Dec 15, 2025
@NCookies NCookies added the enhancement New feature or request label Dec 15, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

📋 개요

이 PR은 사용자 프로필 이미지 삭제 로직을 수정하고, S3 파일명 디코딩을 추가하며, Swagger 설정에 로컬 서버를 추가하고, UserController 문서화를 개선합니다.

🚶 순서도

사용자 프로필 이미지 및 S3 객체 삭제 로직에 대한 수정 사항입니다. 변경 사항은 주로 버그 수정 및 문서화 개선이며, 새로운 제어 흐름을 도입하지 않으므로 시퀀스 다이어그램은 생략합니다.

📝 변경 사항

그룹 / 파일 변경 요약
사용자 프로필 이미지 삭제 로직 수정
src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java
프로필 이미지 삭제 로직을 수정하여 null 확인 대신 StringUtils.hasText()를 사용하여 비어있지 않은 URL일 때만 삭제하도록 변경. oldImageUrl 변수를 사용하여 새 URL 실수로 삭제되는 버그 수정. StringUtils 임포트 추가.
S3 파일명 디코딩 추가
src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java
파일 삭제 시 URLDecoder를 사용하여 파일명을 UTF-8로 디코딩한 후 S3 객체 삭제 수행. URLDecoder 및 StandardCharsets 임포트 추가.
Swagger 설정 개선
src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java
OpenAPI 정의에 로컬 서버 항목(http://localhost:8080) 추가. 기존 프로덕션 서버(https://api.ezcode.my)는 유지.
API 문서화 및 임포트 정리
src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java
사용하지 않는 임포트(LanguageResponse, GrantAdminRoleResponse) 제거. modifyUserInfo 메서드에 Swagger/OpenAPI multipart/form-data 요청 본문 스펙 및 인코딩 어노테이션 추가. Parameter, Content, Encoding 임포트 추가.

📊 예상 코드 리뷰 소요 시간

🎯 3 (보통) | ⏱️ ~20분

세부 검토 항목:

  • UserService의 삭제 로직 수정이 기존 워크플로우와 일관성이 있는지 확인
  • S3Uploader의 URLDecoder 적용이 모든 파일명 형식을 올바르게 처리하는지 검증
  • Swagger 설정 변경이 API 문서 생성에 미치는 영향 확인
  • UserController 어노테이션이 API 클라이언트 생성에 올바르게 적용되는지 검증

🔗 관련 PR

🏷️ 제안 라벨

bug

👥 제안 검토자

  • Kimminu7
  • pokerbearkr
  • thezz9

🐰 축하 시

🐇✨ 버그를 잡아내고 경로를 다듬으며,
URLDecoder 한 방으로 파일명을 구했네!
로컬 서버도 반갑게 인사하고,
이제 이미지는 안전하게 삭제된다네. 🖼️➡️🗑️

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 '회원 정보 수정 API Swagger 및 S3 이미지 삭제 버그 수정'으로, 변경사항의 주요 내용인 Swagger 설정 추가, S3 이미지 삭제 로직 개선, URLDecoder 적용을 정확히 반영합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/s3-profile-bug

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java (2)

83-86: 빈 문자열 검증 추가 권장

URL 디코딩 로직은 올바르지만, fileName이 빈 문자열일 경우를 처리하지 않습니다. PR 요약에서 언급된 대로 UserService는 StringUtils.hasText()로 검증하지만, S3Uploader 자체는 빈 문자열에 대한 방어 로직이 없습니다.

다음 diff를 적용하여 빈 문자열 검증을 추가하세요:

+		if (!StringUtils.hasText(fileName)) {
+			log.warn("S3 삭제 시도: 빈 파일명, URL: {}", fileUrl);
+			return;
+		}
+
 		String decodedFileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8);
 		amazonS3.deleteObject(bucket, decodedFileName);

파일 상단에 import 추가:

+import org.springframework.util.StringUtils;

87-87: 로그 일관성 개선 제안

삭제 작업은 decodedFileName을 사용하지만 로그는 원본 fileName을 출력합니다. 디버깅 시 혼란을 줄 수 있습니다.

로그에 디코딩된 파일명을 출력하도록 변경을 고려하세요:

-		log.info("S3에서 이미지 삭제 완료: {}", fileName);
+		log.info("S3에서 이미지 삭제 완료: {}", decodedFileName);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c0d96a and 894dabe.

📒 Files selected for processing (4)
  • src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java (2 hunks)
  • src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java (2 hunks)
  • src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java (1 hunks)
  • src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (3)
src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java (1)

19-23: 로컬 개발 서버 추가 승인

Swagger UI에서 로컬 환경 테스트를 위한 서버 추가가 적절합니다. 개발 경험을 개선하면서 프로덕션 환경에는 영향을 주지 않습니다.

src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java (1)

105-114: 중요한 버그 수정 확인

프로필 이미지 삭제 로직이 올바르게 수정되었습니다:

  1. oldImageUrl을 엔티티 업데이트 전에 백업 (line 107)
  2. 엔티티를 새 이미지 URL로 업데이트 (line 109)
  3. 백업된 oldImageUrl을 사용하여 S3에서 삭제 (line 112)

StringUtils.hasText() 사용으로 null뿐만 아니라 빈 문자열도 처리하여 더욱 견고합니다. 이전에는 업데이트 후 새 이미지가 삭제되는 버그가 있었는데, 이제 정확히 수정되었습니다.

src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java (1)

50-60: Swagger Content-Type 문제 해결 확인

@RequestBody 어노테이션에 @Encoding을 추가하여 Swagger UI가 request 파트를 application/json으로 전송하도록 강제한 것이 적절합니다. 이전에 발생하던 HttpMediaTypeNotSupportedException 오류가 해결됩니다.

코드 내 한글 주석으로 핵심 수정 사항을 명확히 설명한 점도 좋습니다.

@NCookies NCookies merged commit 28bff8b into dev Dec 15, 2025
2 checks passed
@NCookies NCookies deleted the fix/s3-profile-bug branch December 15, 2025 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants