-
Notifications
You must be signed in to change notification settings - Fork 3
refactor: 제출 로직 리팩토링 #170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: 제출 로직 리팩토링 #170
Conversation
|
""" Walkthrough문제 제출 및 정답 집계 로직에 새로운 이벤트 기반 문제 카운트 조정 기능이 추가되었습니다. Redis 스트림 소비자 관리 및 모니터링이 개선되었고, Judge0 클라이언트의 연결 및 오류 처리 로직이 강화되었습니다. 스레드풀, 데이터베이스, Redis, 스케줄러 등 인프라 설정도 일부 조정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SubmissionService
participant JudgementService
participant SubmissionEventService
participant SubmissionEventListener
participant ProblemService
participant ProblemDomainService
participant ProblemRepository
User->>SubmissionService: processSubmissionAsync(msg)
SubmissionService->>JudgementService: finalizeAndPublish(ctx)
JudgementService->>SubmissionEventService: publishProblemCountAdjustment(event)
SubmissionEventService->>SubmissionEventListener: (이벤트 발행)
SubmissionEventListener->>ProblemService: problemCountAdjustment(problemId, isSolved)
ProblemService->>ProblemDomainService: problemCountAdjustment(problemId, correctInc)
ProblemDomainService->>ProblemRepository: problemCountAdjustment(problemId, correctInc)
Suggested reviewers
Poem
""" ✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (14)
src/main/java/org/ezcode/codetest/infrastructure/scheduler/WeeklyTokenResetScheduler.java (2)
36-39: 크론 표현식을 코드에 하드코딩하기보다 설정 파일로 외부화하는 것을 권장합니다.
"0 0 3 * * MON"값이 비즈니스·운영 요구에 따라 변동될 수 있으므로application.yml(또는application-*.yml)에 프로퍼티로 두고@Value주입이나CronTriggerFactoryBean사용으로 읽어오면 배포 없이도 스케줄을 조정할 수 있습니다.
또한 QA/스테이징 환경에서는 다른 시간대가 필요할 수도 있어 유연성이 커집니다.
41-55: 스케줄 작업 실패 모니터링을 강화하세요.현재 모든 예외를 잡아 로그만 남기고 종료되는데, 장애 감지가 늦어질 위험이 있습니다.
실패 시 알림(예: Slack, Sentry)이나 메트릭(예:Counter/Timerwith Micrometer)을 함께 기록하면 운영 가시성이 높아집니다.src/main/java/org/ezcode/codetest/infrastructure/redis/CommonRedisConfig.java (1)
44-49: 연결 설정에 타임아웃 및 검증 옵션 추가를 고려하세요.현재 설정에는 연결 타임아웃이나 검증 옵션이 없어 네트워크 문제 시 응답이 지연될 수 있습니다.
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .clientResources(resources) .clientOptions(clientOptions) + .commandTimeout(Duration.ofSeconds(10)) .build();src/main/java/org/ezcode/codetest/domain/problem/repository/ProblemRepository.java (1)
25-25: 인터페이스 메서드 선언이 적절합니다.새로운
problemCountAdjustment메서드의 시그니처가 명확하고 구현체와 일치합니다.파라미터 검증을 위한 어노테이션 추가를 고려해보세요:
-void problemCountAdjustment(Long problemId, int correctInc); +void problemCountAdjustment(@NonNull Long problemId, int correctInc);src/main/resources/application.properties (1)
154-162: Hikari Connection Pool 설정이 적절하게 추가되었습니다.제출 로직 리팩토링에 따른 연결 풀 최적화 설정이 합리적으로 구성되었습니다. 설정값들이 일반적인 웹 애플리케이션 워크로드에 적합합니다.
운영 환경에서 실제 워크로드 패턴에 따라 다음 설정들을 모니터링하고 조정하는 것을 권장합니다:
maximum-pool-size: 현재 30으로 설정되어 있으나, 동시 접속자 수에 따라 조정 필요minimum-idle: 트래픽 패턴에 따라 최적화 가능# 모니터링을 위한 JMX 활성화 고려 spring.datasource.hikari.register-mbeans=truesrc/main/java/org/ezcode/codetest/application/submission/dto/event/ProblemCountAdjustmentEvent.java (1)
3-9: 이벤트 레코드 정의가 적절합니다.
ProblemCountAdjustmentEvent레코드가 이벤트 기반 문제 카운트 조정에 필요한 데이터를 명확하게 정의하고 있습니다. 불변 데이터 구조로 레코드를 사용한 것이 적절합니다.이벤트 데이터의 무결성을 위해 검증 로직을 추가하는 것을 고려해보세요:
+import jakarta.validation.constraints.NotNull; + public record ProblemCountAdjustmentEvent( - Long problemId, + @NotNull Long problemId, boolean isSolved ) { + public ProblemCountAdjustmentEvent { + if (problemId == null || problemId <= 0) { + throw new IllegalArgumentException("Problem ID must be positive"); + } + } }src/main/java/org/ezcode/codetest/infrastructure/event/publisher/SubmissionEventPublisher.java (1)
46-49: 새로운 이벤트 발행 메서드가 일관성 있게 구현되었습니다.
publishProblemCountAdjustment메서드가 기존 이벤트 발행 메서드들과 동일한 패턴으로 구현되어 일관성이 유지됩니다.이벤트 발행 실패에 대한 로깅이나 에러 처리를 추가하는 것을 고려해보세요:
+import lombok.extern.slf4j.Slf4j; + +@Slf4j @Component @RequiredArgsConstructor public class SubmissionEventPublisher implements SubmissionEventService { @Override public void publishProblemCountAdjustment(ProblemCountAdjustmentEvent event) { + try { publisher.publishEvent(event); + log.debug("Published problem count adjustment event for problem: {}", event.problemId()); + } catch (Exception e) { + log.error("Failed to publish problem count adjustment event: {}", event, e); + // 필요에 따라 재시도 로직이나 알림 추가 + } }src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java (1)
22-22: 사용하지 않는 import 제거 필요
Propagationimport가 파일에서 사용되지 않고 있습니다.-import org.springframework.transaction.annotation.Propagation;src/main/java/org/ezcode/codetest/infrastructure/event/scheduler/RedisStreamMonitor.java (1)
19-31: Redis 스트림 모니터링 기본 구현이 적절하지만 개선 여지 있음5분 간격 모니터링으로 PR 목표의 Redis 연결 문제를 해결하는 기본적인 구현입니다. 프로덕션 환경에서의 안정성을 위해 다음 개선사항을 고려해보세요:
- 지수 백오프 재시도 로직
- 연속 실패 시 알림 메커니즘
- 헬스체크 메트릭 수집
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemJpaRepository.java (1)
26-36: JPQL 업데이트 쿼리 구현이 효율적이나 존재 검증 추가 권장배치 업데이트를 위한
@Modifying(clearAutomatically = true)사용이 적절하고, 두 카운트를 동시에 업데이트하는 쿼리도 효율적입니다.존재하지 않는 problemId로 호출 시 조용히 실패할 수 있으므로, 상위 레이어에서 문제 존재 여부를 검증하거나 업데이트 결과를 확인하는 것을 고려해보세요.
src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java (1)
62-65: 이벤트 기반 문제 수 조정 리스너 구현이 적절하나 예외 처리 추가 권장
AFTER_COMMIT단계를 사용하여 트랜잭션 커밋 후에만 문제 수 조정이 실행되도록 한 설계가 안전합니다.
problemService.problemCountAdjustment()호출 시 예외 발생 시 이벤트가 손실될 수 있으므로, 로깅이나 재시도 로직을 추가하는 것을 고려해보세요.@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void onProblemCountAdjustment(ProblemCountAdjustmentEvent event) { - problemService.problemCountAdjustment(event.problemId(), event.isSolved()); + try { + problemService.problemCountAdjustment(event.problemId(), event.isSolved()); + } catch (Exception e) { + log.error("문제 수 조정 실패: problemId={}, isSolved={}", event.problemId(), event.isSolved(), e); + } }src/main/java/org/ezcode/codetest/domain/submission/model/SubmissionResult.java (1)
21-30: 문제 해결 상태 판단 로직에 주석 추가를 권장합니다.현재 로직은 "이전에 풀지 못했고 이번에 처음으로 모든 테스트를 통과한 경우"만
isSolved = true로 설정합니다. 이 의도를 명확히 하기 위해 주석을 추가하는 것이 좋겠습니다.다음과 같이 주석을 추가하세요:
public static SubmissionResult of(UserProblemResult upr, List<String> problemCategory, boolean allPassed) { + // before: 이전 정답 여부, now: 이번에 새롭게 정답 처리되는지 여부 boolean before = upr.isCorrect(); boolean now = allPassed && !before;src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConsumerRegistrar.java (1)
38-45: UUID 길이를 늘려 충돌 가능성을 줄이는 것을 권장합니다.현재 UUID의 처음 8자만 사용하고 있는데, 이는 드물지만 충돌 가능성이 있습니다. 더 긴 UUID를 사용하면 안전성이 향상됩니다.
다음과 같이 수정하세요:
- return "consumer-" + UUID.randomUUID().toString().substring(0, 8); + return "consumer-" + UUID.randomUUID().toString().substring(0, 12);src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConfig.java (1)
85-86: 에러 핸들러에 복구 로직 추가를 고려하세요.현재 에러 핸들러는 로그만 남기고 있습니다. PR 설명에 따르면 Redis 연결이 끊어지는 문제를 해결했다고 하는데, 에러 발생 시 자동 복구 메커니즘이 필요할 수 있습니다.
RedisStreamMonitor가 컨테이너 상태를 모니터링한다면, 에러 핸들러에서 모니터에 알림을 보내는 방식으로 개선할 수 있습니다. 이에 대한 구현을 도와드릴까요?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java(2 hunks)src/main/java/org/ezcode/codetest/application/submission/dto/event/ProblemCountAdjustmentEvent.java(1 hunks)src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java(1 hunks)src/main/java/org/ezcode/codetest/application/submission/port/SubmissionEventService.java(2 hunks)src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java(4 hunks)src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java(0 hunks)src/main/java/org/ezcode/codetest/common/config/ExecutorConfig.java(3 hunks)src/main/java/org/ezcode/codetest/domain/problem/repository/ProblemRepository.java(1 hunks)src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java(2 hunks)src/main/java/org/ezcode/codetest/domain/submission/model/SubmissionResult.java(1 hunks)src/main/java/org/ezcode/codetest/domain/submission/service/SubmissionDomainService.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConfig.java(4 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConsumerRegistrar.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java(3 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/publisher/SubmissionEventPublisher.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/scheduler/RedisStreamMonitor.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java(3 hunks)src/main/java/org/ezcode/codetest/infrastructure/lock/RedisLockManager.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemJpaRepository.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemRepositoryImpl.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/submission/query/SubmissionQueryRepositoryImpl.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/redis/CommonRedisConfig.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/scheduler/WeeklyTokenResetScheduler.java(1 hunks)src/main/resources/application.properties(1 hunks)
💤 Files with no reviewable changes (1)
- src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: thezz9
PR: ezcode-my/backend#36
File: src/main/java/org/ezcode/codetest/domain/problem/model/entity/ProblemLanguage.java:3-3
Timestamp: 2025-06-06T07:57:51.226Z
Learning: 사용자 thezz9는 Language 엔티티를 Submission 도메인으로 이동시킨 이유가 "제출하려면 필요해서"라고 설명했으며, Problem 도메인과 Submission 도메인 간의 종속성 위반 문제에 대한 해결 방안을 고민하고 있다.
Learnt from: chat26666
PR: ezcode-my/backend#37
File: src/main/java/org/ezcode/codetest/infrastructure/elasticsearch/repository/ProblemElasticsearchRepositoryDsl.java:10-10
Timestamp: 2025-06-06T19:56:27.759Z
Learning: When user chat26666 mentions that code was implemented in a previous PR but explanation was missing, they may submit a follow-up PR just to add documentation/explanation without the actual implementation code.
Learnt from: thezz9
PR: ezcode-my/backend#111
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:58-73
Timestamp: 2025-06-27T09:53:52.378Z
Learning: User thezz9 acknowledges technical issues when flagged but often indicates they will address them later ("나중에 바꿀 겨"), suggesting they prioritize getting core functionality working first before refining implementation details.
Learnt from: thezz9
PR: ezcode-my/backend#75
File: src/main/java/org/ezcode/codetest/application/submission/aop/CodeReviewLockAspect.java:25-41
Timestamp: 2025-06-19T06:37:57.845Z
Learning: User thezz9 tends to skip validation for scenarios they consider unlikely to occur, but is willing to implement defensive programming practices when suggested for code robustness.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:93-96
Timestamp: 2025-06-28T02:04:24.957Z
Learning: User thezz9 sometimes temporarily uses less secure or inconsistent exception handling (like RuntimeException with raw error bodies) for debugging purposes when error messages are being hidden in the normal application flow, but acknowledges this as technical debt and fixes it once debugging is complete.
Learnt from: thezz9
PR: ezcode-my/backend#132
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java:72-72
Timestamp: 2025-07-02T09:39:31.485Z
Learning: User thezz9 prefers to proceed with breaking changes to path structures when it improves the organization, rather than maintaining backward compatibility or implementing migration strategies.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:159-165
Timestamp: 2025-06-28T02:03:38.693Z
Learning: User thezz9's service (ezcode) targets Korean users exclusively ("찐 한국인밖에 안 옴"), so Korean language hardcoding in commit messages and UI elements is intentional and appropriate for their use case.
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemRepositoryImpl.java (2)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
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해야 합니다.
src/main/java/org/ezcode/codetest/domain/problem/repository/ProblemRepository.java (2)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
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해야 합니다.
src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java (2)
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해야 합니다.
Learnt from: chat26666
PR: ezcode-my/backend#31
File: src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java:25-27
Timestamp: 2025-06-04T15:11:19.343Z
Learning: In ProblemDomainService, when saving problems to both database and Elasticsearch, maintain transactional consistency by allowing rollback if either save operation fails. Data integrity between DB and ES is prioritized over availability - if Elasticsearch save fails, the entire transaction should roll back to prevent data inconsistency.
src/main/java/org/ezcode/codetest/application/submission/port/SubmissionEventService.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#98
File: src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java:17-22
Timestamp: 2025-06-25T01:24:30.773Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java (2)
Learnt from: thezz9
PR: ezcode-my/backend#120
File: src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java:58-64
Timestamp: 2025-06-30T10:10:07.449Z
Learning: Judge0Client에서 Reactor의 retryWhen() 재시도가 모두 실패했을 때 발생하는 RetryExhaustedException은 package-private 클래스라서 직접 import할 수 없으므로, 부모 클래스인 IllegalStateException을 catch해서 COMPILE_TIMEOUT으로 매핑하는 것이 필요한 해결책이다.
Learnt from: thezz9
PR: ezcode-my/backend#98
File: src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java:17-22
Timestamp: 2025-06-25T01:24:30.773Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConsumerRegistrar.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#68
File: src/main/java/org/ezcode/codetest/infrastructure/event/listener/RedisJudgeQueueConsumer.java:43-45
Timestamp: 2025-06-17T02:49:32.334Z
Learning: Spring Data Redis의 StreamOperations.acknowledge() 메서드는 acknowledge(String group, MapRecord... records) 시그니처를 지원하며, Consumer 객체 없이도 그룹명과 메시지 레코드만으로 ACK 처리가 가능합니다.
src/main/java/org/ezcode/codetest/infrastructure/event/scheduler/RedisStreamMonitor.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#68
File: src/main/java/org/ezcode/codetest/infrastructure/event/listener/RedisJudgeQueueConsumer.java:43-45
Timestamp: 2025-06-17T02:49:32.334Z
Learning: Spring Data Redis의 StreamOperations.acknowledge() 메서드는 acknowledge(String group, MapRecord... records) 시그니처를 지원하며, Consumer 객체 없이도 그룹명과 메시지 레코드만으로 ACK 처리가 가능합니다.
src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java (2)
Learnt from: chat26666
PR: ezcode-my/backend#31
File: src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java:25-27
Timestamp: 2025-06-04T15:11:19.343Z
Learning: In ProblemDomainService, when saving problems to both database and Elasticsearch, maintain transactional consistency by allowing rollback if either save operation fails. Data integrity between DB and ES is prioritized over availability - if Elasticsearch save fails, the entire transaction should roll back to prevent data inconsistency.
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해야 합니다.
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemJpaRepository.java (3)
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java:0-0
Timestamp: 2025-06-15T04:37:29.231Z
Learning: EncounterChoiceRepositoryImpl in src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/EncounterChoiceRepositoryImpl.java is intentionally a skeleton implementation that is work-in-progress and will be completed later.
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해야 합니다.
Learnt from: Kimminu7
PR: ezcode-my/backend#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일 수 있다.
src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java (3)
Learnt from: chat26666
PR: ezcode-my/backend#67
File: src/main/java/org/ezcode/codetest/domain/game/service/CharacterEquipService.java:26-34
Timestamp: 2025-06-16T16:07:34.354Z
Learning: 이 프로젝트에서는 UseCase 레벨에서 트랜잭션 경계를 관리하므로, 도메인 서비스 클래스들(예: CharacterEquipService)에는 @Transactional 어노테이션이 필요하지 않습니다. 트랜잭션은 UseCase에서 열리므로 데이터 일관성이 보장됩니다.
Learnt from: thezz9
PR: ezcode-my/backend#30
File: src/main/java/org/ezcode/codetest/domain/problem/service/SubmissionDomainService.java:24-33
Timestamp: 2025-06-04T13:12:28.354Z
Learning: The submission evaluation system is currently in testing phase, so hardcoded expected output values like "12" are intentionally used for testing purposes rather than being a production issue.
Learnt from: chat26666
PR: ezcode-my/backend#31
File: src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java:25-27
Timestamp: 2025-06-04T15:11:19.343Z
Learning: In ProblemDomainService, when saving problems to both database and Elasticsearch, maintain transactional consistency by allowing rollback if either save operation fails. Data integrity between DB and ES is prioritized over availability - if Elasticsearch save fails, the entire transaction should roll back to prevent data inconsistency.
src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConfig.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#68
File: src/main/java/org/ezcode/codetest/infrastructure/event/listener/RedisJudgeQueueConsumer.java:43-45
Timestamp: 2025-06-17T02:49:32.334Z
Learning: Spring Data Redis의 StreamOperations.acknowledge() 메서드는 acknowledge(String group, MapRecord... records) 시그니처를 지원하며, Consumer 객체 없이도 그룹명과 메시지 레코드만으로 ACK 처리가 가능합니다.
🧬 Code Graph Analysis (1)
src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConsumerRegistrar.java (2)
src/main/java/org/ezcode/codetest/infrastructure/event/scheduler/RedisStreamMonitor.java (1)
Slf4j(11-32)src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConfig.java (1)
Slf4j(21-96)
⏰ 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 (16)
src/main/java/org/ezcode/codetest/infrastructure/lock/RedisLockManager.java (1)
18-18: 작업 완료 시간 검증 결과 필요
tryLock이 사용되는 메서드는 아래 3곳으로 확인되었습니다.
- RedisLockManager.tryLock
- LockManager 인터페이스
- CodeReviewLockAspect (AOP로 감싼 실제 비즈니스 메서드)
그러나 이 검색만으로는 각 비즈니스 메서드(Aspect가 적용되는 대상)의 실제 실행 시간이 1분 이내인지 알 수 없습니다.
따라서 아래 항목을 추가로 검사해 주세요**:**• CodeReviewLockAspect의 포인트컷(pointcut)에 해당하는 비즈니스 메서드들을 식별
• 각 메서드의 평균/최장 실행 시간(로그, 메트릭, 로컬 프로파일링 등)을 확인
• 1분 잠금 시간으로 충분한지 별도 검증위 항목 검증 후, 1분 잠금 설정이 적절하다면 머지 진행, 아니라면 잠금 지속 시간을 재조정해주세요.
src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java (1)
169-171: 간단하고 명확한 구현입니다.이벤트 기반 문제 카운트 조정 메커니즘을 지원하기 위한 편의 메서드가 잘 구현되었습니다.
src/main/java/org/ezcode/codetest/application/submission/port/SubmissionEventService.java (2)
4-4: 이벤트 기반 아키텍처 확장을 위한 적절한 import 추가.새로운 문제 카운트 조정 이벤트 지원을 위한 import가 추가되었습니다.
22-22: 인터페이스 확장이 기존 패턴을 잘 따르고 있습니다.새로운 이벤트 발행 메서드가 기존 메서드들과 일관성 있게 구현되었습니다.
src/main/java/org/ezcode/codetest/common/config/ExecutorConfig.java (3)
28-30: judgeSubmissionExecutor 설정 확인.제출 처리 스레드 풀의 크기가 동일하게 증가했습니다.
39-41: judgeTestcaseExecutor 큐 용량이 가장 큽니다.테스트케이스 실행 스레드 풀의 큐 용량이 2000으로 다른 풀보다 큽니다. 테스트케이스 처리량이 많다는 것을 반영한 것으로 보입니다.
17-19: 스레드 풀 증가: OS 제한 및 메모리 영향 검증 완료
- ulimit -u: 128,368 ⇒ 총 240개 스레드 요구량 대비 충분
- 예상 스레드 스택 메모리: 240 MB ~ 480 MB (1 MB×총 스레드 수) ⇒ 허용 범위 내
그러나 CPU 컨텍스트 스위칭 오버헤드와 실제 워크로드에서의 성능 영향은 추가 검증이 필요합니다.
검토 대상:
- src/main/java/org/ezcode/codetest/common/config/ExecutorConfig.java (17–19행)
- executor.setCorePoolSize(5); - executor.setMaxPoolSize(10); - executor.setQueueCapacity(100); + executor.setCorePoolSize(40); + executor.setMaxPoolSize(80); + executor.setQueueCapacity(1000);시스템 모니터링, 점진적 롤아웃, 부하 테스트를 통해 CPU 부하 및 응답 지연 여부를 확인하세요.
src/main/java/org/ezcode/codetest/infrastructure/event/publisher/SubmissionEventPublisher.java (1)
4-4: 새로운 이벤트 임포트가 적절합니다.
ProblemCountAdjustmentEvent임포트가 올바르게 추가되었습니다.src/main/java/org/ezcode/codetest/domain/problem/service/ProblemDomainService.java (1)
130-132: 문제 수 조정 로직 구현이 적절함도메인 서비스에서 리포지토리로의 단순한 위임 패턴으로 잘 구현되었습니다. 이벤트 기반 문제 통계 업데이트 아키텍처에 적합합니다.
src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java (1)
197-201: 트랜잭션 격리를 통한 데드락 방지 구현이 우수함
REQUIRES_NEW전파 옵션 사용으로 문제 수 업데이트가 별도 트랜잭션에서 실행되어 PR 목표에서 언급된 데드락 문제를 효과적으로 해결합니다. boolean을 int로 변환하는 로직도 명확합니다.src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java (2)
111-115: SubmissionContext#getProblemId 메서드가 정상적으로 정의되어 있습니다.
SubmissionContext클래스 하단에 이미public Long getProblemId()가 구현되어 있으므로 추가 수정이 필요 없습니다.
61-61: @transactional 적용은 서비스 계층에서 일관되게 사용됩니다.기존 서비스 클래스들에도 이미 @transactional이 적용되어 있어, JudgementService에 해당 어노테이션을 추가하는 것은 아키텍처 패턴과 일치합니다.
또한SubmissionContext#getProblemId()메서드는SubmissionContext클래스에 정의되어 있어 호출에 문제가 없습니다.Likely an incorrect or invalid review comment.
src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/submission/query/SubmissionQueryRepositoryImpl.java (1)
30-51: 사용자 기반 쿼리로의 변경이 적절합니다.LEFT JOIN을 사용하여 제출이 없는 사용자도 결과에 포함되도록 한 것은 PR 목적("제출이 0건인 유저도 토큰을 받을 수 있도록")과 일치합니다. 쿼리 구조 개선이 잘 되었습니다.
src/main/java/org/ezcode/codetest/domain/submission/service/SubmissionDomainService.java (1)
38-53: 제출 통계 업데이트 이벤트 처리 검증 완료JudgementService에서
publishProblemCountAdjustment로 이벤트를 발행하고,
SubmissionEventListener.onProblemCountAdjustment에서problemService.problemCountAdjustment를 호출하여 카운트 업데이트가 정상 처리됨을 확인했습니다.src/main/java/org/ezcode/codetest/infrastructure/event/config/RedisStreamConfig.java (2)
28-30: 컨슈머 등록 중앙화가 잘 구현되었습니다.
RedisStreamConsumerRegistrar를 사용하여 컨슈머 관리를 중앙화한 것은 좋은 설계 결정입니다.
30-30: 리뷰 코멘트: 컨테이너 필드 스레드 안전성 이슈 없음
RedisStreamConfig.container필드는 스프링이 애플리케이션 시작 시 단일 스레드에서 한 번만 초기화합니다.RedisStreamMonitor는RedisStreamConfig의 필드를 직접 참조하지 않고, 별도의final필드에 주입된 동일한 Bean 인스턴스를 사용합니다.- 따라서
volatile키워드나 추가 동기화는 불필요합니다.Likely an incorrect or invalid review comment.
src/main/java/org/ezcode/codetest/infrastructure/redis/CommonRedisConfig.java
Outdated
Show resolved
Hide resolved
...org/ezcode/codetest/infrastructure/persistence/repository/problem/ProblemRepositoryImpl.java
Show resolved
Hide resolved
src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java
Outdated
Show resolved
Hide resolved
| ConnectionProvider provider = ConnectionProvider.builder("judge0-pool") | ||
| .maxConnections(1000) | ||
| .pendingAcquireMaxCount(2000) | ||
| .pendingAcquireTimeout(Duration.ofSeconds(60)) | ||
| .build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
ConnectionProvider의 maxConnections 값이 너무 높게 설정되어 있습니다.
maxConnections(1000)은 매우 큰 값입니다. 이는 Judge0 서버에 과부하를 줄 수 있으며, 실제로 이만큼의 동시 연결이 필요한지 검토가 필요합니다. 일반적으로 외부 API의 경우 50-200 정도의 연결 풀이 적절합니다.
PR 목적에 언급된 "Thread, Hikari, WebClient의 풀 사이즈 조정"과 관련이 있다면, 실제 부하 테스트 결과를 바탕으로 적절한 값을 설정하는 것을 권장합니다.
🤖 Prompt for AI Agents
In src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java
around lines 44 to 48, the maxConnections value for the ConnectionProvider is
set too high at 1000, which risks overloading the Judge0 server. Reduce
maxConnections to a more reasonable number between 50 and 200 based on expected
load or results from load testing. Adjust pendingAcquireMaxCount accordingly to
maintain a balanced connection pool size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 많이 줄일 수가 없어.
최악의 상황일 경우 테스트 케이스가 8개인 문제를 10명이 동시 제출을 한다고 가정,
8 * 10에 get token + polling 생각하면 이것만 해도 160이야
그래서 일단 500으로 줄여놓긴 했는데, 더 줄이면 동시 제출을 그만큼 못 받게 돼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thezz9 좋은 분석이네요! 동시 제출 시나리오를 고려한 계산이 합리적입니다.
테스트 케이스 8개 × 10명 동시 제출 + 토큰 획득/폴링 오버헤드로 160개 이상의 연결이 필요하다는 계산이 맞고, 500으로 설정한 것이 적절한 버퍼를 제공하는 것 같습니다. 일반적인 외부 API 가이드라인보다는 높지만, 귀하의 구체적인 사용 사례를 고려하면 타당한 선택입니다.
✏️ Learnings added
Learnt from: thezz9
PR: ezcode-my/backend#170
File: src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java:0-0
Timestamp: 2025-07-15T15:26:17.738Z
Learning: Judge0Client에서 ConnectionProvider의 maxConnections가 500으로 설정된 이유는 동시 제출 시나리오 때문입니다. 최악의 경우 테스트 케이스 8개 × 10명 동시 제출 + 토큰 획득/폴링 오버헤드로 약 160개 이상의 연결이 필요하며, 500은 이를 위한 적절한 버퍼를 제공합니다.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: thezz9
PR: ezcode-my/backend#30
File: src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java:44-46
Timestamp: 2025-06-04T13:12:17.636Z
Learning: SubmissionService에서 "2 10" 입력값과 "12" 기대출력이 하드코딩되어 있는 것은 테스트 단계의 의도적인 구현이며, 추후 Problem 엔티티의 실제 테스트케이스로 대체 예정입니다.
Learnt from: thezz9
PR: ezcode-my/backend#120
File: src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java:58-64
Timestamp: 2025-06-30T10:10:07.449Z
Learning: Judge0Client에서 Reactor의 retryWhen() 재시도가 모두 실패했을 때 발생하는 RetryExhaustedException은 package-private 클래스라서 직접 import할 수 없으므로, 부모 클래스인 IllegalStateException을 catch해서 COMPILE_TIMEOUT으로 매핑하는 것이 필요한 해결책이다.
Learnt from: thezz9
PR: ezcode-my/backend#75
File: src/main/java/org/ezcode/codetest/application/submission/aop/CodeReviewLockAspect.java:25-41
Timestamp: 2025-06-19T06:37:57.845Z
Learning: User thezz9 tends to skip validation for scenarios they consider unlikely to occur, but is willing to implement defensive programming practices when suggested for code robustness.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:93-96
Timestamp: 2025-06-28T02:04:24.957Z
Learning: User thezz9 sometimes temporarily uses less secure or inconsistent exception handling (like RuntimeException with raw error bodies) for debugging purposes when error messages are being hidden in the normal application flow, but acknowledges this as technical debt and fixes it once debugging is complete.
Learnt from: thezz9
PR: ezcode-my/backend#132
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java:72-72
Timestamp: 2025-07-02T09:39:31.485Z
Learning: User thezz9 prefers to proceed with breaking changes to path structures when it improves the organization, rather than maintaining backward compatibility or implementing migration strategies.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:159-165
Timestamp: 2025-06-28T02:03:38.693Z
Learning: User thezz9's service (ezcode) targets Korean users exclusively ("찐 한국인밖에 안 옴"), so Korean language hardcoding in commit messages and UI elements is intentional and appropriate for their use case.
Learnt from: thezz9
PR: ezcode-my/backend#36
File: src/main/java/org/ezcode/codetest/domain/problem/model/entity/ProblemLanguage.java:3-3
Timestamp: 2025-06-06T07:57:51.226Z
Learning: 사용자 thezz9는 Language 엔티티를 Submission 도메인으로 이동시킨 이유가 "제출하려면 필요해서"라고 설명했으며, Problem 도메인과 Submission 도메인 간의 종속성 위반 문제에 대한 해결 방안을 고민하고 있다.
Learnt from: chat26666
PR: ezcode-my/backend#37
File: src/main/java/org/ezcode/codetest/infrastructure/elasticsearch/repository/ProblemElasticsearchRepositoryDsl.java:10-10
Timestamp: 2025-06-06T19:56:27.759Z
Learning: When user chat26666 mentions that code was implemented in a previous PR but explanation was missing, they may submit a follow-up PR just to add documentation/explanation without the actual implementation code.
Learnt from: thezz9
PR: ezcode-my/backend#111
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:58-73
Timestamp: 2025-06-27T09:53:52.378Z
Learning: User thezz9 acknowledges technical issues when flagged but often indicates they will address them later ("나중에 바꿀 겨"), suggesting they prioritize getting core functionality working first before refining implementation details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅇㅋ 나중에 문제 생기면 더 줄이던가 할게
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thezz9 네, 좋은 접근 방식이네요! 현재 설정으로 운영해보시고 필요에 따라 조정하시면 될 것 같습니다. 실제 사용 패턴을 보면서 최적화하는 것이 가장 확실한 방법이죠.
🧠 Learnings used
Learnt from: thezz9
PR: ezcode-my/backend#170
File: src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java:0-0
Timestamp: 2025-07-15T15:26:17.738Z
Learning: Judge0Client에서 ConnectionProvider의 maxConnections가 500으로 설정된 이유는 동시 제출 시나리오 때문입니다. 최악의 경우 테스트 케이스 8개 × 10명 동시 제출 + 토큰 획득/폴링 오버헤드로 약 160개 이상의 연결이 필요하며, 500은 이를 위한 적절한 버퍼를 제공합니다.
Learnt from: thezz9
PR: ezcode-my/backend#111
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:58-73
Timestamp: 2025-06-27T09:53:52.378Z
Learning: User thezz9 acknowledges technical issues when flagged but often indicates they will address them later ("나중에 바꿀 겨"), suggesting they prioritize getting core functionality working first before refining implementation details.
Learnt from: thezz9
PR: ezcode-my/backend#30
File: src/main/java/org/ezcode/codetest/domain/problem/model/dto/SubmissionData.java:42-53
Timestamp: 2025-06-04T13:12:16.729Z
Learning: 사용자 thezz9는 개발 시 기능적 정확성을 먼저 달성한 후 세부 리팩터링을 나중에 하는 접근 방식을 선호한다. 테스트 단계에서는 하드코딩된 값도 허용한다.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:159-165
Timestamp: 2025-06-28T02:03:38.693Z
Learning: User thezz9's service (ezcode) targets Korean users exclusively ("찐 한국인밖에 안 옴"), so Korean language hardcoding in commit messages and UI elements is intentional and appropriate for their use case.
Learnt from: thezz9
PR: ezcode-my/backend#30
File: src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java:44-46
Timestamp: 2025-06-04T13:12:17.636Z
Learning: SubmissionService에서 "2 10" 입력값과 "12" 기대출력이 하드코딩되어 있는 것은 테스트 단계의 의도적인 구현이며, 추후 Problem 엔티티의 실제 테스트케이스로 대체 예정입니다.
Learnt from: thezz9
PR: ezcode-my/backend#36
File: src/main/java/org/ezcode/codetest/domain/problem/model/entity/ProblemLanguage.java:3-3
Timestamp: 2025-06-06T07:57:51.226Z
Learning: 사용자 thezz9는 Language 엔티티를 Submission 도메인으로 이동시킨 이유가 "제출하려면 필요해서"라고 설명했으며, Problem 도메인과 Submission 도메인 간의 종속성 위반 문제에 대한 해결 방안을 고민하고 있다.
Learnt from: thezz9
PR: ezcode-my/backend#120
File: src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java:58-64
Timestamp: 2025-06-30T10:10:07.449Z
Learning: Judge0Client에서 Reactor의 retryWhen() 재시도가 모두 실패했을 때 발생하는 RetryExhaustedException은 package-private 클래스라서 직접 import할 수 없으므로, 부모 클래스인 IllegalStateException을 catch해서 COMPILE_TIMEOUT으로 매핑하는 것이 필요한 해결책이다.
Learnt from: thezz9
PR: ezcode-my/backend#75
File: src/main/java/org/ezcode/codetest/application/submission/aop/CodeReviewLockAspect.java:25-41
Timestamp: 2025-06-19T06:37:57.845Z
Learning: User thezz9 tends to skip validation for scenarios they consider unlikely to occur, but is willing to implement defensive programming practices when suggested for code robustness.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:93-96
Timestamp: 2025-06-28T02:04:24.957Z
Learning: User thezz9 sometimes temporarily uses less secure or inconsistent exception handling (like RuntimeException with raw error bodies) for debugging purposes when error messages are being hidden in the normal application flow, but acknowledges this as technical debt and fixes it once debugging is complete.
Learnt from: thezz9
PR: ezcode-my/backend#132
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java:72-72
Timestamp: 2025-07-02T09:39:31.485Z
Learning: User thezz9 prefers to proceed with breaking changes to path structures when it improves the organization, rather than maintaining backward compatibility or implementing migration strategies.
Learnt from: chat26666
PR: ezcode-my/backend#37
File: src/main/java/org/ezcode/codetest/infrastructure/elasticsearch/repository/ProblemElasticsearchRepositoryDsl.java:10-10
Timestamp: 2025-06-06T19:56:27.759Z
Learning: When user chat26666 mentions that code was implemented in a previous PR but explanation was missing, they may submit a follow-up PR just to add documentation/explanation without the actual implementation code.
There was a problem hiding this 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/test/java/org/ezcode/codetest/infrastructure/judge0/Judge0ClientTest.java (2)
153-153: 테스트 타임아웃 값을 상수화하여 유지보수성을 개선하세요.하드코딩된 11초 값이 Judge0Client의 실제 타임아웃 설정과 일치하는지 확인이 필요합니다. 테스트의 가독성과 유지보수성을 위해 상수로 정의하는 것을 권장합니다.
+ private static final int TIMEOUT_TEST_DELAY_SECONDS = 11; + mockWebServer.enqueue(new MockResponse() .setBody("{\"token\":\"late\"}") .setHeader("Content-Type", "application/json") - .setBodyDelay(11, TimeUnit.SECONDS)); + .setBodyDelay(TIMEOUT_TEST_DELAY_SECONDS, TimeUnit.SECONDS));
185-185: 폴링 반복 횟수를 상수화하여 테스트 의도를 명확히 하세요.61회로 감소한 반복 횟수가 실제 Judge0Client의 폴링 타임아웃 로직과 일치하는지 확인이 필요합니다. 매직 넘버 대신 의미 있는 상수명을 사용하는 것을 권장합니다.
+ private static final int POLLING_TIMEOUT_ATTEMPTS = 61; + - for (int i = 0; i < 61; i++) { + for (int i = 0; i < POLLING_TIMEOUT_ATTEMPTS; i++) { mockWebServer.enqueue(json("{\"status\":{\"id\":1}}")); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/org/ezcode/codetest/domain/submission/model/SubmissionResult.java(2 hunks)src/main/java/org/ezcode/codetest/domain/submission/service/SubmissionDomainService.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java(3 hunks)src/main/java/org/ezcode/codetest/infrastructure/redis/CommonRedisConfig.java(1 hunks)src/test/java/org/ezcode/codetest/domain/submission/SubmissionDomainServiceTest.java(5 hunks)src/test/java/org/ezcode/codetest/infrastructure/judge0/Judge0ClientTest.java(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java
- src/main/java/org/ezcode/codetest/domain/submission/service/SubmissionDomainService.java
- src/main/java/org/ezcode/codetest/infrastructure/redis/CommonRedisConfig.java
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: thezz9
PR: ezcode-my/backend#36
File: src/main/java/org/ezcode/codetest/domain/problem/model/entity/ProblemLanguage.java:3-3
Timestamp: 2025-06-06T07:57:51.226Z
Learning: 사용자 thezz9는 Language 엔티티를 Submission 도메인으로 이동시킨 이유가 "제출하려면 필요해서"라고 설명했으며, Problem 도메인과 Submission 도메인 간의 종속성 위반 문제에 대한 해결 방안을 고민하고 있다.
Learnt from: chat26666
PR: ezcode-my/backend#37
File: src/main/java/org/ezcode/codetest/infrastructure/elasticsearch/repository/ProblemElasticsearchRepositoryDsl.java:10-10
Timestamp: 2025-06-06T19:56:27.759Z
Learning: When user chat26666 mentions that code was implemented in a previous PR but explanation was missing, they may submit a follow-up PR just to add documentation/explanation without the actual implementation code.
Learnt from: thezz9
PR: ezcode-my/backend#111
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:58-73
Timestamp: 2025-06-27T09:53:52.378Z
Learning: User thezz9 acknowledges technical issues when flagged but often indicates they will address them later ("나중에 바꿀 겨"), suggesting they prioritize getting core functionality working first before refining implementation details.
Learnt from: thezz9
PR: ezcode-my/backend#75
File: src/main/java/org/ezcode/codetest/application/submission/aop/CodeReviewLockAspect.java:25-41
Timestamp: 2025-06-19T06:37:57.845Z
Learning: User thezz9 tends to skip validation for scenarios they consider unlikely to occur, but is willing to implement defensive programming practices when suggested for code robustness.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:93-96
Timestamp: 2025-06-28T02:04:24.957Z
Learning: User thezz9 sometimes temporarily uses less secure or inconsistent exception handling (like RuntimeException with raw error bodies) for debugging purposes when error messages are being hidden in the normal application flow, but acknowledges this as technical debt and fixes it once debugging is complete.
Learnt from: thezz9
PR: ezcode-my/backend#132
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java:72-72
Timestamp: 2025-07-02T09:39:31.485Z
Learning: User thezz9 prefers to proceed with breaking changes to path structures when it improves the organization, rather than maintaining backward compatibility or implementing migration strategies.
Learnt from: thezz9
PR: ezcode-my/backend#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:159-165
Timestamp: 2025-06-28T02:03:38.693Z
Learning: User thezz9's service (ezcode) targets Korean users exclusively ("찐 한국인밖에 안 옴"), so Korean language hardcoding in commit messages and UI elements is intentional and appropriate for their use case.
src/test/java/org/ezcode/codetest/infrastructure/judge0/Judge0ClientTest.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#120
File: src/main/java/org/ezcode/codetest/infrastructure/judge0/Judge0Client.java:58-64
Timestamp: 2025-06-30T10:10:07.449Z
Learning: Judge0Client에서 Reactor의 retryWhen() 재시도가 모두 실패했을 때 발생하는 RetryExhaustedException은 package-private 클래스라서 직접 import할 수 없으므로, 부모 클래스인 IllegalStateException을 catch해서 COMPILE_TIMEOUT으로 매핑하는 것이 필요한 해결책이다.
src/main/java/org/ezcode/codetest/domain/submission/model/SubmissionResult.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#36
File: src/main/java/org/ezcode/codetest/domain/submission/dto/SubmissionData.java:47-58
Timestamp: 2025-06-06T07:59:41.806Z
Learning: SubmissionData.withAggregatedStats() 메서드에서 testCaseList는 상위 프로세스(base() 메서드의 problemInfo.testcaseList())에서 이미 null 체크가 처리되어 오므로 추가적인 null 체크가 불필요함
src/test/java/org/ezcode/codetest/domain/submission/SubmissionDomainServiceTest.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#30
File: src/main/java/org/ezcode/codetest/domain/problem/service/SubmissionDomainService.java:24-33
Timestamp: 2025-06-04T13:12:28.354Z
Learning: The submission evaluation system is currently in testing phase, so hardcoded expected output values like "12" are intentionally used for testing purposes rather than being a production issue.
⏰ 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 (9)
src/test/java/org/ezcode/codetest/infrastructure/judge0/Judge0ClientTest.java (1)
153-153: 타임아웃 설정 변경에 따른 테스트 조정이 적절합니다.Judge0Client의 타임아웃 설정이 5초에서 10초로 변경된 것에 맞춰 테스트 케이스를 조정한 것은 올바른 접근입니다. 실제 구현의 동작과 테스트가 일치하도록 유지하는 것이 중요합니다.
Also applies to: 185-185
src/main/java/org/ezcode/codetest/domain/submission/model/SubmissionResult.java (3)
5-5: 새로운 의존성 추가 확인
SubmissionContext의존성이 추가되었습니다. 이는 정적 팩토리 메서드의 시그니처 변경과 일치합니다.
22-27: 메서드 시그니처 변경 검토메서드명이
from에서of로 변경되고 파라미터 구조가 개선되었습니다. 개별 파라미터들을SubmissionContext로 통합하여 응집도를 높였습니다.
28-34: 핵심 로직 변경:isSolved플래그 검증 필요
SubmissionResult.of(...)내부에서.isSolved(allPassed && !before) .hasBeenSolved(before)로직으로 바뀌면서, 기존
result.isCorrect()가 아니라 “이전에 풀지 않았고 현재 모든 테스트를 통과했을 때만isSolved=true**”**가 되도록 변경되었습니다. 이 변경이 실제 비즈니스 요구사항(신규 풀이 vs. 재풀이 구분)과 일치하는지 꼭 검토해 주세요.점검 대상:
- src/main/java/org/ezcode/codetest/domain/submission/model/SubmissionResult.java (28–34행):
isSolved/hasBeenSolved할당 확인- src/main/java/org/ezcode/codetest/domain/submission/service/SubmissionDomainService.java (38–58행):
before값 계산 및SubmissionResult.of(...)사용부위 플래그들이 상위 계층(Controller/UI)에서 의도대로 표시·처리되는지 함께 검증을 요청드립니다.
src/test/java/org/ezcode/codetest/domain/submission/SubmissionDomainServiceTest.java (5)
122-124: 첫 번째 정답 제출 테스트 개선
hasBeenSolved()검증이 추가되어 "이전에 풀지 않았던 문제를 처음 맞췄을 때"의 상태를 정확히 검증합니다.
163-163: 첫 번째 오답 제출 테스트 개선첫 번째 오답 제출 시
hasBeenSolved()상태가 올바르게 검증되고 있습니다.
202-204: 재시도 후 정답 테스트 개선오답 상태에서 정답으로 변경될 때의 상태 변화를 정확히 검증합니다 - 새로 푼 것으로 간주되고 이전에 풀지 않았던 상태를 반영합니다.
244-244: 재시도 후 재오답 테스트 개선연속된 오답 제출 시의 상태가 올바르게 검증되고 있습니다.
284-286: 이미 푼 문제 재제출 테스트 로직 검증이미 정답인 문제에 대한 재제출 시:
isSolved()= false (새로 푼 것이 아니므로)hasBeenSolved()= true (이전에 이미 풀었으므로)이 로직은 중복 정답 처리에 대한 비즈니스 규칙을 정확히 반영하고 있습니다.
작업 내용
해결해야 할 문제
Summary by CodeRabbit
신규 기능
개선 사항
버그 수정
기타