Skip to content

Conversation

@thezz9
Copy link
Collaborator

@thezz9 thezz9 commented Sep 2, 2025

Summary by CodeRabbit

  • 신기능
    • 문제 상세 화면에 대표 테스트케이스 2개가 추가되어, 입·출력 예시를 즉시 확인할 수 있습니다.
  • 리팩터링
    • 문제 상세 조회 시 테스트케이스를 함께 불러오도록 데이터 로딩 경로를 조정해 화면 일관성을 개선했습니다.
  • 테스트
    • 변경된 데이터 조회 흐름에 맞춰 테스트를 업데이트하고, 불필요한 의존성을 정리했습니다.

@thezz9 thezz9 self-assigned this Sep 2, 2025
@thezz9 thezz9 added the enhancement New feature or request label Sep 2, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 2, 2025

Walkthrough

문제 상세 응답 DTO에 테스트케이스 목록 필드를 추가하고, 도메인 서비스가 리포지토리에서 테스트케이스를 포함해 문제를 조회하도록 변경했다. Problem 엔티티에 상위 2개 테스트케이스를 반환하는 메서드를 추가했고, 관련 테스트는 새 리포지토리 메서드로 업데이트됐다.

Changes

Cohort / File(s) Change Summary
DTO 업데이트
src/main/java/.../application/problem/dto/response/ProblemDetailResponse.java, src/main/java/.../application/problem/dto/response/TestcaseResponse.java
ProblemDetailResponse에 List<TestcaseResponse> testcases 필드 추가 및 from(...)에서 problem.top2Testcases() 매핑해 세팅. imageUrl 뒤 콤마로 필드 추가 반영. TestcaseResponse의 불필요한 Problem import 제거.
도메인 엔티티 변경
src/main/java/.../domain/problem/model/entity/Problem.java
incrementTotalSubmissions, incrementCorrectSubmissions 제거. top2Testcases() 추가(테스트케이스 ID 오름차순 정렬 후 최대 2개 반환). Comparator import 추가.
도메인 서비스 및 테스트
src/main/java/.../domain/problem/service/ProblemDomainService.java, src/test/java/.../domain/problem/service/ProblemDomainServiceTest.java
조회 메서드를 findByIdNotDeletedfindProblemWithTestcasesById로 변경하여 테스트케이스를 포함해 문제 조회. 단위 테스트에서도 동일 메서드로 스텁/검증 변경.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant Service as ProblemDomainService
    participant Repo as ProblemRepository
    participant Entity as Problem
    participant DTO as ProblemDetailResponse

    Client->>Service: getProblem(problemId)
    Service->>Repo: findProblemWithTestcasesById(problemId)
    Repo-->>Service: Optional<Problem(with testcases)>

    alt Problem found
        Service->>Entity: top2Testcases()
        Entity-->>Service: List<Testcase>(≤2, sorted by id)
        Service->>DTO: from(Problem, mapped TestcaseResponse list)
        DTO-->>Service: ProblemDetailResponse
        Service-->>Client: ProblemDetailResponse
    else Not found
        Service-->>Client: throw NotFoundException
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Kimminu7
  • pokerbearkr
  • minjee2758
  • NCookies
  • chat26666

Poem

귀 쫑긋, 코드밭에 새 싹 돋네 🌱
두 알 테스트, 살짝 맛만 보게 둘러 담고
문제는 케이스와 함께 집으로 Hop!
오래된 가지는 정리하고 🍃
당근빛 리스폰스에 봄바람이 분다 🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/problem-detail

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@thezz9 thezz9 merged commit dc0d318 into dev Sep 2, 2025
1 of 2 checks passed
@thezz9 thezz9 deleted the refactor/problem-detail branch September 2, 2025 12:12
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: 1

🧹 Nitpick comments (3)
src/test/java/org/ezcode/codetest/domain/problem/service/ProblemDomainServiceTest.java (1)

93-94: 리포지토리 메서드 변경 반영 OK

findProblemWithTestcasesById로의 스텁/검증 업데이트가 적절합니다.

보완 권장:

  • “삭제된 문제는 조회 불가” 케이스를 추가해 soft-delete 필터를 회귀 방지하세요.

예시 테스트 추가(참고):

@Test
@DisplayName("삭제된 문제 조회 시 예외")
void getProblem_deleted_throws() {
    Long problemId = 1L;
    Problem problem = mock(Problem.class);
    when(problemRepository.findProblemWithTestcasesById(problemId)).thenReturn(Optional.of(problem));
    when(problem.getIsDeleted()).thenReturn(true); // 리포지토리가 필터를 보장하지 않는 경우 대비
    assertThrows(ProblemException.class, () -> problemDomainService.getProblem(problemId));
}

리포지토리가 이미 필터를 보장한다면 위 테스트는 리포지토리 단위 테스트로 이동하거나 서비스에서의 방어 로직을 생략해도 됩니다.

Also applies to: 101-102

src/main/java/org/ezcode/codetest/application/problem/dto/response/ProblemDetailResponse.java (2)

54-56: 신규 필드 스키마 명세 추가 및 네이밍 컨벤션 확인

API 문서 가독성을 위해 testcases에 스키마 설명을 붙이는 것을 권장합니다. 또한 기존 필드들이 lowerCamelCase를 따르는 만큼, testcases vs testCases 네이밍을 한 번 더 결정해 주세요(신규 필드라 호환성 부담이 낮습니다).

스키마 주석 예시(간단):

- String imageUrl,
-
- List<TestcaseResponse> testcases
+ String imageUrl,
+
+ @Schema(description = "입출력 예시(최대 2건)")
+ List<TestcaseResponse> testcases

75-76: LazyInitializationException 위험 없음: ProblemDetailResponse.from@Transactional(readOnly=true)이 적용된 ProblemService.getProblem 내에서 호출되며, ProblemDomainService.getProblem의 fetch-join으로 테스트케이스가 이미 로드됩니다.

  • (권장) 상세 화면에 상위 2건만 필요하다면 TestcaseRepository.findTop2ByProblemIdOrderByIdAsc 같은 별도 쿼리로 I/O를 최적화하세요.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dd15a92 and 2c02191.

📒 Files selected for processing (5)
  • src/main/java/org/ezcode/codetest/application/problem/dto/response/ProblemDetailResponse.java (2 hunks)
  • src/main/java/org/ezcode/codetest/application/problem/dto/response/TestcaseResponse.java (0 hunks)
  • src/main/java/org/ezcode/codetest/domain/problem/model/entity/Problem.java (2 hunks)
  • src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java (1 hunks)
  • src/test/java/org/ezcode/codetest/domain/problem/service/ProblemDomainServiceTest.java (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/org/ezcode/codetest/application/problem/dto/response/TestcaseResponse.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-02T12:05:54.917Z
Learnt from: Kimminu7
PR: ezcode-my/backend#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/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java
  • src/test/java/org/ezcode/codetest/domain/problem/service/ProblemDomainServiceTest.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 (1)
src/main/java/org/ezcode/codetest/domain/problem/model/entity/Problem.java (1)

4-4: top2Testcases 성능 및 NPE 안전성 선택적 개선 제안

  • 대규모 testcases 리스트에서 매 호출 O(n log n) 정렬 비용이 부담된다면,
    @onetomany 필드에
    @OrderBy("id ASC")
    를 추가한 뒤
    return testcases.isEmpty() ? List.of() : List.copyOf(testcases.subList(0, Math.min(2, testcases.size())));
    로 슬라이싱해 O(n)으로 개선할 수 있습니다.
  • Testcase.id@GeneratedValue(strategy = GenerationType.IDENTITY) 적용 시 영속화 후 non-null이 보장되므로 NPE 우려는 사실상 없습니다.
    – 영속화 전 호출할 가능성이 있다면,
    .sorted(Comparator.comparing(Testcase::getId, Comparator.nullsLast(Comparator.naturalOrder())))
    처럼 null-safe 정렬을 선택하세요.

Comment on lines +100 to 102
return problemRepository.findProblemWithTestcasesById(problemId)
.orElseThrow(() -> new ProblemException(ProblemExceptionCode.PROBLEM_NOT_FOUND));
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

findProblemWithTestcasesById가 soft-delete 필터를 포함하는지 확인 필요

기존 findByIdNotDeleted에서 전환되며 삭제된 문제 노출 위험이 생길 수 있습니다. 리포지토리 쿼리에 isDeleted = false 조건과 테스트케이스 fetch-join이 포함되는지 확인해 주세요. 미보장 시, 리포지토리 수정 또는 방어적 체크 추가가 필요합니다.

검증 스크립트:

추가 제안(옵션):

  • 본 메서드가 다양한 호출처에서 사용된다면, 안전망으로 조회 후 problem.getIsDeleted() 체크를 넣는 것도 고려해 주세요.
  • 읽기 전용 쿼리 메서드(getProblem, getProblemInfo)에 @Transactional(readOnly = true) 부여를 검토하면 LAZY 초기화/성능 측면에서 안전합니다.

🏁 Script executed:

#!/bin/bash
# ProblemRepository 에서 쿼리와 soft-delete 필터 확인
rg -nP --type java -C3 '\binterface\s+ProblemRepository\b'
rg -nP --type java -C6 '\bfindProblemWithTestcasesById\s*\('
# 쿼리 본문/스펙 내 isDeleted 필터 존재 여부 확인
rg -nP --type java -C3 'findProblemWithTestcasesById|isDeleted|fetch\s+join'

Length of output: 57295


ProblemJpaRepository.findProblemWithTestcasesById에 soft-delete 필터(isDeleted = false) 추가
현재 JPA 쿼리에 p.isDeleted = false 조건이 빠져 있어 삭제된(soft-deleted) 문제도 조회될 수 있습니다. where p.isDeleted = false and p.id = :problemId로 쿼리를 수정하거나, 서비스 계층에서 조회 후 problem.getIsDeleted() 방어적 체크를 추가해 주세요.

🤖 Prompt for AI Agents
In
src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java
around lines 100 to 102, the repository call returns soft-deleted entities
because the JPA query lacks a p.isDeleted = false filter; update the repository
method findProblemWithTestcasesById to include where p.isDeleted = false and
p.id = :problemId so deleted problems are never returned, or if you cannot
change the repository right now, add a defensive check after retrieval to throw
ProblemException(ProblemExceptionCode.PROBLEM_NOT_FOUND) when
problem.getIsDeleted() == true; ensure only non-deleted problems are treated as
found.

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