Skip to content

Conversation

@minjee2758
Copy link
Collaborator

@minjee2758 minjee2758 commented Dec 26, 2025

PR 생성 시 아래 항목을 채워주세요.

제목 예시: feat : Pull request template 작성

(작성 후 이 안내 문구는 삭제해주세요)


작업 내용

  • 어떤 기능(또는 수정 사항)을 구현했는지 간략하게 설명해주세요.
  • 예) "회원가입 API에 이메일 중복 검사 기능 추가"

변경 사항

  • 구현한 주요 로직, 클래스, 메서드 등을 bullet 형식으로 기술해주세요.
  • 예)
    • UserService.createUser() 메서드 추가
    • @Email 유효성 검증 적용

트러블 슈팅

  • 구현 중 마주한 문제와 해결 방법을 기술해주세요.
  • 예)
    • 문제: @Transactional이 적용되지 않음
    • 해결: 메서드 호출 방식 변경 (this.AopProxyUtils. 사용)

해결해야 할 문제

  • 기능은 동작하지만 리팩토링이나 논의가 필요한 부분을 적어주세요.
  • 예)D
    • UserController에서 비즈니스 로직 일부 처리 → 서비스로 이전 고려 필요

참고 사항

  • 기타 공유하고 싶은 정보나 참고한 문서(링크 등)가 있다면 작성해주세요.

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

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

Summary by CodeRabbit

릴리스 노트

  • 버그 수정

    • 이미지 파일이 없을 때 업로드 시도 시 향상된 오류 처리 추가
  • 개선사항

    • 카테고리 데이터 구조 최적화

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

@coderabbitai
Copy link

coderabbitai bot commented Dec 26, 2025

개요

문제 카테고리 데이터 구조를 List에서 Map으로 변경하고, 이미지 업로드 시 파일 유효성 검사를 추가하며, 관련 S3 예외 코드를 신규 추가하여 요청 DTO, 서비스 로직, 도메인 서비스 및 테스트를 일관되게 업데이트했습니다.

변경사항

응집군 / 파일 변경 요약
카테고리 데이터 구조 변경
src/main/java/org/ezcode/codetest/application/problem/dto/request/ProblemUpdateRequest.java, src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java
categories 필드 타입을 List<String>에서 Map<String, String>으로 변경. 카테고리 코드를 키로, 표시명을 값으로 사용. Swagger 스키마 주석도 맵 구조를 반영하도록 업데이트
이미지 파일 검증 추가
src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java
addImageToExistingProblem 메서드에 null/빈 imageFile 검증 로직 추가. 유효하지 않으면 S3_FILE_EMPTY 예외 코드로 S3Exception 발생
S3 예외 코드 확장
src/main/java/org/ezcode/codetest/infrastructure/s3/exception/code/S3ExceptionCode.java
새로운 enum 상수 S3_FILE_EMPTY(false, HttpStatus.BAD_REQUEST, "업로드할 이미지 파일이 없습니다."); 추가
테스트 업데이트
src/test/java/org/ezcode/codetest/application/problem/service/ProblemServiceTest.java
modifyProblem 테스트에서 categories를 List에서 Map으로 변경하고, updateCategoryAndSearchEngine 호출 시 Map 파라미터를 사용하도록 조정

예상 코드 리뷰 난이도

🎯 2 (Simple) | ⏱️ ~12분

관련 가능성 있는 PR

추천 레이블

enhancement

추천 리뷰어

  • Kimminu7
  • NCookies
  • chat26666
  • pokerbearkr

시 🐰

리스트에서 맵으로, 코드도 춤을 춘다네 🗺️
카테고리 키와 값으로 단장하고,
이미지 파일이 공허할 땐 경고를!
S3의 새로운 친구 FILE_EMPTY 등장 🚀
테스트도 함께 춤춘다, 모두 완벽하게! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 수정이라는 두 가지 목표를 명확하게 언급하고 있으며, 실제 변경사항(이미지 유효성 검사 추가, 카테고리 필드 타입 변경 등)과 관련성이 있습니다.
✨ 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 refactor/all-problem-correction

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java (2)

51-62: categories 파라미터가 null인 경우 NullPointerException 발생 가능

categories.keySet() 호출 전에 null 체크가 없습니다. 호출자가 null을 전달하면 NPE가 발생합니다.

🔎 null 방어 코드 추가 제안
 public void updateCategoryAndSearchEngine(Problem problem, Map<String, String> categories) {
 
 	problemCategoryRepository.deleteAllByProblemId(problem.getId());
 
+	if (categories == null || categories.isEmpty()) {
+		return;
+	}
+
 	List<String> codes = new ArrayList<>(categories.keySet());
 	List<Category> categoryList = categoryRepository.findAllByCategoryCodeIn(codes);

65-84: createProblem에서도 동일한 null 체크 필요

updateCategoryAndSearchEngine과 동일하게 categories가 null인 경우를 방어해야 합니다. 또한 두 메서드에서 카테고리 코드 추출 및 저장 로직이 중복되어 있습니다.

🔎 null 체크 및 공통 로직 추출 제안
 public Problem createProblem(Problem problem, Map<String, String> categories) {
 
 	if (problemRepository.existsByTitleAndIsDeletedIsFalse(problem.getTitle())) {
 		throw new ProblemException(ProblemExceptionCode.DUPLICATE_PROBLEM);
 	}
 
 	Problem savedProblem = problemRepository.save(problem);
 
+	if (categories == null || categories.isEmpty()) {
+		return savedProblem;
+	}
+
 	List<String> codes = new ArrayList<>(categories.keySet());

공통 로직 추출 (선택사항):

private void saveProblemCategories(Problem problem, Map<String, String> categories) {
    if (categories == null || categories.isEmpty()) {
        return;
    }
    List<String> codes = new ArrayList<>(categories.keySet());
    List<Category> categoryList = categoryRepository.findAllByCategoryCodeIn(codes);
    List<ProblemCategory> problemCategories = categoryList.stream()
        .map(cat -> ProblemCategory.from(problem, cat))
        .toList();
    problemCategoryRepository.saveAll(problemCategories);
}
🧹 Nitpick comments (1)
src/test/java/org/ezcode/codetest/application/problem/service/ProblemServiceTest.java (1)

195-204: addImageToExistingProblem의 새로운 검증 로직에 대한 테스트 추가 권장

ProblemService.addImageToExistingProblem에 추가된 null/empty 이미지 검증 로직에 대한 테스트 케이스가 없습니다.

🔎 테스트 케이스 추가 예시
@Test
@DisplayName("이미지 추가 시 빈 파일이면 예외 발생")
void addImageToExistingProblem_shouldThrowExceptionWhenImageEmpty() {
    // given
    MultipartFile emptyFile = mock(MultipartFile.class);
    when(emptyFile.isEmpty()).thenReturn(true);

    // when & then
    assertThrows(S3Exception.class, () -> 
        problemService.addImageToExistingProblem(1L, emptyFile));
}

@Test
@DisplayName("이미지 추가 시 null 파일이면 예외 발생")
void addImageToExistingProblem_shouldThrowExceptionWhenImageNull() {
    // when & then
    assertThrows(S3Exception.class, () -> 
        problemService.addImageToExistingProblem(1L, null));
}
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c991519 and ac68058.

📒 Files selected for processing (5)
  • src/main/java/org/ezcode/codetest/application/problem/dto/request/ProblemUpdateRequest.java
  • src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java
  • src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java
  • src/main/java/org/ezcode/codetest/infrastructure/s3/exception/code/S3ExceptionCode.java
  • src/test/java/org/ezcode/codetest/application/problem/service/ProblemServiceTest.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-06-14T14:33:58.372Z
Learnt from: Kimminu7
Repo: ezcode-my/backend PR: 63
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemQueryRepositoryImpl.java:24-40
Timestamp: 2025-06-14T14:33:58.372Z
Learning: ProblemController에서 ProblemSearchCondition 객체는 항상 new ProblemSearchCondition(category, difficulty)로 유효한 인스턴스를 생성해서 전달하므로, ProblemQueryRepositoryImpl의 searchByCondition 메서드에서 searchCondition 파라미터 자체에 대한 null 체크는 불필요하다. category와 difficulty 필드만 각각 null일 수 있다.

Applied to files:

  • src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java
📚 Learning: 2025-07-02T12:05:54.917Z
Learnt from: Kimminu7
Repo: ezcode-my/backend PR: 133
File: src/test/java/org/ezcode/codetest/domain/problem/service/ProblemDomainServiceTest.java:92-99
Timestamp: 2025-07-02T12:05:54.917Z
Learning: ProblemDomainService의 removeProblem 메서드는 DB에서 Problem을 삭제한 후 Elasticsearch에서도 해당 ProblemSearchDocument를 찾아서 삭제합니다. 만약 Elasticsearch에서 문서를 찾지 못하면 ProblemException(PROBLEM_NOT_FOUND)을 던지므로, 테스트에서는 problem.getId()와 searchRepository.findById() 모두 적절하게 mock해야 합니다.

Applied to files:

  • src/test/java/org/ezcode/codetest/application/problem/service/ProblemServiceTest.java
⏰ 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 (5)
src/main/java/org/ezcode/codetest/infrastructure/s3/exception/code/S3ExceptionCode.java (1)

16-17: LGTM!

새로운 S3_FILE_EMPTY 상수가 기존 패턴을 잘 따르고 있으며, 클라이언트 측 검증 오류에 대해 HttpStatus.BAD_REQUEST를 적절하게 사용하고 있습니다.

src/main/java/org/ezcode/codetest/application/problem/dto/request/ProblemUpdateRequest.java (1)

14-16: Map의 값(value)이 사용되지 않음 - 의도 확인 필요

categories 필드가 Map<String, String>으로 변경되었지만, ProblemDomainService에서는 키(코드)만 추출하여 사용하고 있습니다. Map의 값(한글 이름)은 사용되지 않습니다.

의도적인 설계인지 확인이 필요합니다:

  • API 문서화/가독성 목적이라면 현재 구조가 적절합니다.
  • 값을 사용할 계획이 없다면 List<String>이 더 간결할 수 있습니다.

또한 Swagger example 형식이 JSON Map 구문과 다릅니다.

🔎 Swagger example 수정 제안
-	@Schema(description = "카테고리 코드 식별자(영어) / 한글 이름", example = "FOR_BEGINNER : 입문자용")
+	@Schema(description = "카테고리 코드 식별자(영어) / 한글 이름", example = "{\"FOR_BEGINNER\": \"입문자용\"}")
 	Map<String, String> categories,
src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java (2)

193-196: LGTM!

이미지 파일의 null/empty 검증이 적절하게 추가되었습니다. 새로 추가된 S3_FILE_EMPTY 예외 코드를 활용하여 명확한 오류 메시지를 제공합니다.


144-147: 불필요한 지적입니다. getImageUrl()은 null을 반환할 수 없습니다.

imageUrl 필드는 선언 시점에 new ArrayList<>()로 초기화되며, 어디서도 null로 설정되지 않습니다. 또한 Problem 엔티티의 addImage()(150줄), clearImages()(155줄) 메서드에서도 imageUrl에 대해 직접 메서드를 호출하고 있으므로, 개발자들도 이 필드가 null이 아님을 알고 있습니다. @ElementCollection JPA 어노테이션도 컬렉션을 항상 초기화된 상태로 유지합니다. 코드베이스의 다른 부분(ProblemDetailResponse 74줄)에서도 동일한 패턴으로 null 체크 없이 isEmpty()를 호출하고 있습니다.

src/test/java/org/ezcode/codetest/application/problem/service/ProblemServiceTest.java (1)

166-172: LGTM!

테스트가 ProblemDomainService.updateCategoryAndSearchEngine의 변경된 시그니처(Map<String, String>)에 맞게 적절히 업데이트되었습니다.

@minjee2758 minjee2758 merged commit 0d632c6 into dev Dec 26, 2025
2 checks passed
@minjee2758 minjee2758 deleted the refactor/all-problem-correction branch December 26, 2025 03:50
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.

2 participants