-
Notifications
You must be signed in to change notification settings - Fork 3
refactor : 파일 2개 커밋 하나로 병합하는 로직 구현 (99.7%) #114
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
Conversation
|
""" Walkthrough이 변경사항은 GitHub로 코드 푸시 기능을 대대적으로 리팩토링하고 확장합니다. 기존 GitHubService를 GitHubPushService로 대체하고, 푸시 상태 이벤트 및 예외 처리를 도입하며, GitHub API 클라이언트를 세분화된 메서드 기반으로 재구성합니다. 또한, 푸시 상태를 실시간으로 전송하는 이벤트-리스너 구조가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SubmissionEventListener
participant SubmissionService
participant GitHubPushService
participant UserGitHubService
participant GitHubClientImpl
participant SubmissionEventPublisher
participant StompMessageService
User->>SubmissionEventListener: 코드 제출 메시지 수신
SubmissionEventListener->>SubmissionService: processSubmissionAsync(msg)
SubmissionService->>GitHubPushService: pushSolutionToRepo(ctx)
GitHubPushService->>SubmissionEventPublisher: publishGitPushStatus(STARTED)
GitHubPushService->>UserGitHubService: getUserGithubInfo()
GitHubPushService->>GitHubClientImpl: commitAndPushToRepo(req)
alt 성공
GitHubPushService->>SubmissionEventPublisher: publishGitPushStatus(SUCCESS)
else 실패
GitHubPushService->>SubmissionEventPublisher: publishGitPushStatus(FAILED)
end
SubmissionEventPublisher->>SubmissionEventListener: GitPushStatusEvent
SubmissionEventListener->>StompMessageService: sendGitStatus(sessionKey, response)
StompMessageService->>User: 실시간 푸시 상태 메시지 전송
Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (1)📓 Common learnings🔇 Additional comments (3)
✨ 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 (7)
src/main/resources/application.properties (1)
149-155: 보안 키와 커스텀 섹션 주석 정리가 필요합니다
aes.secret.key는 외부 변수로 잘 빼셨지만, 동일 키를 여러 환경에서 재사용하지 않도록 주의하세요.github.repo.root-folder는 “git push” 섹션 하위에 있지만 접두어가git.이 아니라github.입니다. 향후 확장을 고려해 prefix를 통일하거나 문서에 명시하면 혼선을 줄일 수 있습니다.src/main/java/org/ezcode/codetest/infrastructure/github/model/FileType.java (1)
8-17: 파일명 생성 로직에 방어적 프로그래밍 추가를 고려해보세요.현재 구현은 깔끔하지만 다음 개선사항을 제안합니다:
req매개변수와 해당 필드들에 대한 null 체크 추가Extensions.getExtensionByLanguage()메서드의 존재 여부 확인public String resolveFilename(GitHubPushRequest req) { + if (req == null) { + throw new IllegalArgumentException("GitHubPushRequest cannot be null"); + } return switch (this) { case SOURCE -> String.format("%s.%s", req.problemTitle(), Extensions.getExtensionByLanguage(req.languageName()) ); case README -> String.format("README_%s.md", req.languageName().toLowerCase() ); }; }src/main/java/org/ezcode/codetest/infrastructure/github/model/Extensions.java (1)
17-24: 언어별 확장자 매핑 로직이 잘 구현되었으나 개선 사항이 있습니다.enum과 정적 메서드 구조는 적절하지만 다음 사항을 고려해보세요:
- 예외 메시지가 한국어로 하드코딩되어 있습니다. 국제화를 고려한 메시지 처리를 권장합니다.
IllegalArgumentException대신 도메인별 예외 타입을 정의하는 것을 고려해보세요.예외 메시지를 개선한 예시:
- throw new IllegalArgumentException("지원하지 않는 언어입니다: " + languageName); + throw new UnsupportedLanguageException("Unsupported language: " + languageName);src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java (1)
40-62: 마크다운 템플릿에서 불필요한 빈 줄을 정리하세요.44-47번째 줄에 연속된 빈 줄이 있어 마크다운 가독성을 해칠 수 있습니다.
다음과 같이 수정하는 것을 권장합니다:
- 제출 일자: %s - %s - - ### 제출 요약src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java (3)
44-71: 반환 타입의 일관성 개선 필요다른 SHA를 가져오는 메서드들(
fetchHeadCommitSha,fetchBaseTreeSha)은String을 직접 반환하는데, 이 메서드만Optional<String>을 반환합니다. API 설계의 일관성을 위해 통일된 접근 방식을 고려해보세요.또한 파일 경로 구조가 하드코딩되어 있어 다른 레포지토리 구조에 대한 유연성이 부족합니다.
107-113: 커밋과 푸시 로직이 잘 분리되어 있습니다두 개의 작업을 명확하게 분리하여 가독성이 좋습니다. 다만, 커밋은 성공하고 브랜치 업데이트가 실패할 경우를 고려하여 로깅이나 롤백 전략을 추가로 고려해보세요.
70-71: 리액티브 프로그래밍의 이점 활용 고려모든 WebClient 호출에서
.block()을 사용하여 동기적으로 처리하고 있습니다. 이는 리액티브 스택의 논블로킹 I/O 이점을 활용하지 못하게 합니다.전체 아키텍처가 리액티브를 지원한다면,
Mono나Flux를 반환하도록 리팩토링하여 성능을 개선할 수 있습니다. 동기 처리가 필요한 경우라면, 이에 대한 문서화를 추가하는 것이 좋겠습니다.Also applies to: 102-103, 128-129, 148-149, 181-182, 201-202
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
src/main/java/org/ezcode/codetest/application/submission/dto/event/GitPushStatusEvent.java(1 hunks)src/main/java/org/ezcode/codetest/application/submission/dto/request/github/GitHubPushRequest.java(2 hunks)src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java(2 hunks)src/main/java/org/ezcode/codetest/application/submission/port/SubmissionEventService.java(2 hunks)src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java(1 hunks)src/main/java/org/ezcode/codetest/application/submission/service/GitHubService.java(0 hunks)src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java(3 hunks)src/main/java/org/ezcode/codetest/domain/submission/exception/GitHubClientException.java(1 hunks)src/main/java/org/ezcode/codetest/domain/submission/exception/code/GitHubExceptionCode.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/dto/submission/response/GitPushStatusResponse.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/listener/RedisJudgeQueueConsumer.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/publisher/StompMessageService.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/publisher/SubmissionEventPublisher.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/GitBlobCalculator.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/model/CommitContext.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/model/Extensions.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/model/FileType.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/github/model/PushStatus.java(1 hunks)src/main/resources/application.properties(3 hunks)
💤 Files with no reviewable changes (1)
- src/main/java/org/ezcode/codetest/application/submission/service/GitHubService.java
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
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: minjee2758
PR: ezcode-my/backend#110
File: src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java:102-112
Timestamp: 2025-06-27T06:03:05.687Z
Learning: `CustomOAuth2UserService`의 `updateGithubUrl` 메서드는 새로운 유저 생성 시나 기존 유저가 새로운 AuthType을 추가할 때만 호출되므로, `UserGithubInfo` 중복 생성 가능성이 없다. 별도의 중복 체크 로직이 불필요하다.
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.
src/main/java/org/ezcode/codetest/infrastructure/event/listener/RedisJudgeQueueConsumer.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/resources/application.properties (1)
Learnt from: minjee2758
PR: ezcode-my/backend#43
File: src/main/resources/application.properties:83-86
Timestamp: 2025-06-10T02:08:35.347Z
Learning: 이 프로젝트에서는 OAuth2 개발 작업을 위해 DEBUG 및 TRACE 레벨 로깅을 유지하는 것을 선호합니다.
src/main/java/org/ezcode/codetest/domain/submission/exception/GitHubClientException.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.754Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
src/main/java/org/ezcode/codetest/infrastructure/github/model/Extensions.java (1)
Learnt from: thezz9
PR: ezcode-my/backend#36
File: src/main/java/org/ezcode/codetest/application/submission/dto/request/compile/CodeCompileRequest.java:5-9
Timestamp: 2025-06-06T07:52:58.941Z
Learning: CodeCompileRequest 레코드의 필드명(source_code, language_id)은 Java camelCase 컨벤션 대신 snake_case를 사용하는데, 이는 Judge0 API의 반환 값 형식에 맞추기 위한 의도적인 설계 결정이다.
src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java (1)
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.
src/main/java/org/ezcode/codetest/domain/submission/exception/code/GitHubExceptionCode.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.754Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
🧬 Code Graph Analysis (3)
src/main/java/org/ezcode/codetest/domain/submission/exception/GitHubClientException.java (1)
src/main/java/org/ezcode/codetest/common/base/exception/BaseException.java (1)
BaseException(5-12)
src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java (1)
src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java (1)
Component(16-96)
src/main/java/org/ezcode/codetest/domain/submission/exception/code/GitHubExceptionCode.java (1)
src/main/java/org/ezcode/codetest/domain/submission/exception/GitHubClientException.java (1)
Getter(10-22)
🪛 ast-grep (0.38.1)
src/main/java/org/ezcode/codetest/infrastructure/github/GitBlobCalculator.java
[warning] 20-20: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Instead, use PBKDF2 for password hashing or SHA256 or SHA512 for other hash function applications.
Context: MessageDigest.getInstance("SHA-1")
Note: [CWE-328] Use of Weak Hash. [REFERENCES]
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
(use-of-sha1-java)
🔇 Additional comments (35)
src/main/resources/application.properties (1)
20-20: SQL 포맷팅을 끄면 로그 가독성이 급격히 떨어집니다
운영 환경의 로그 부피 절감 목적이라면 dev 프로필에서는true를 유지하도록 profile-specific 설정을 권장합니다.src/main/java/org/ezcode/codetest/infrastructure/github/model/CommitContext.java (1)
3-10: 깔끔한 record 구현입니다.GitHub 커밋 컨텍스트를 위한 불변 데이터 구조로 적절하게 설계되었습니다. record 패턴을 사용하여 간결하고 명확한 구현을 제공합니다.
src/main/java/org/ezcode/codetest/infrastructure/github/GitBlobCalculator.java (3)
21-21: Git 컨텍스트에서 SHA-1 사용은 적절합니다.정적 분석 도구에서 SHA-1 사용에 대한 보안 경고가 발생했지만, Git blob 해시 계산의 경우 Git의 표준 해시 알고리즘이므로 이 컨텍스트에서는 적절합니다. Git 자체가 SHA-1을 사용하여 blob 객체를 식별하므로 호환성을 위해 필요합니다.
14-28: Git blob 형식을 정확히 구현했습니다.Git의 내부 blob 객체 형식(
blob <size>\0<content>)을 정확히 따라 구현되었으며, SHA-1 해시 계산 로직도 올바릅니다. 바이트 배열 조작과 16진수 변환 로직이 적절합니다.
11-11: protected 접근 제한자 사용 이유를 확인해보세요.메서드가
protected로 선언되어 있는데, 이는 상속을 고려한 설계인지 확인이 필요합니다. 현재 컨텍스트에서public이 더 적절할 수 있습니다.다음 스크립트로 이 클래스의 상속 관계를 확인해보세요:
#!/bin/bash # Description: GitBlobCalculator 클래스의 상속 관계 확인 # GitBlobCalculator를 상속하는 클래스 검색 ast-grep --pattern 'class $_ extends GitBlobCalculator { $$$ }' # GitBlobCalculator의 메서드를 호출하는 코드 검색 rg -A 3 "calculateBlobSha"src/main/java/org/ezcode/codetest/infrastructure/event/listener/RedisJudgeQueueConsumer.java (1)
39-39: 메서드 이름 변경으로 의미가 더 명확해졌습니다.
submitCodeStream에서processSubmissionAsync로 변경되어 비동기 처리 의도가 더 명확하게 표현되었습니다. 메서드 시그니처가 호환되는지 확인이 필요합니다.다음 스크립트로 새로운 메서드의 시그니처를 확인해보세요:
#!/bin/bash # Description: SubmissionService의 processSubmissionAsync 메서드 시그니처 확인 # processSubmissionAsync 메서드 정의 찾기 ast-grep --pattern 'processSubmissionAsync($msg) { $$$ }' # SubmissionMessage 타입의 매개변수를 받는 메서드 찾기 rg -A 5 "processSubmissionAsync.*SubmissionMessage"src/main/java/org/ezcode/codetest/application/submission/port/SubmissionEventService.java (2)
3-3: 새로운 이벤트 타입에 대한 import가 적절히 추가되었습니다.
GitPushStatusEvent클래스에 대한 import가 올바르게 추가되어 새로운 기능을 지원합니다.
19-19: 일관된 인터페이스 설계를 따랐습니다.새로 추가된
publishGitPushStatus메서드가 기존의 다른 publish 메서드들과 일관된 네이밍 패턴을 따르고 있어 인터페이스의 일관성을 유지합니다.src/main/java/org/ezcode/codetest/infrastructure/event/publisher/SubmissionEventPublisher.java (2)
3-3: 필요한 import가 적절히 추가되었습니다.
GitPushStatusEvent에 대한 import가 새로운 메서드 구현을 위해 올바르게 추가되었습니다.
40-43: 기존 패턴과 일치하는 일관된 구현입니다.새로 추가된
publishGitPushStatus메서드가 기존의 다른 publish 메서드들과 동일한 패턴을 따라 구현되어 코드 일관성을 유지합니다.ApplicationEventPublisher를 통한 이벤트 발행 로직이 적절합니다.src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java (1)
53-57: 새로운 Git 푸시 상태 이벤트 리스너가 올바르게 구현되었습니다.기존 이벤트 리스너들과 동일한 패턴을 따르고 있으며,
GitPushStatusEvent를 수신하여 적절한 WebSocket 응답으로 변환하고 있습니다.src/main/java/org/ezcode/codetest/infrastructure/github/model/FileType.java (1)
11-11: 다음 스크립트로Extensions클래스와getExtensionByLanguage메서드의 실제 존재 여부를 전체 코드베이스에서 확인해 주세요.#!/bin/bash # Extensions 클래스 파일 위치 및 선언 검색 rg -n "class Extensions" --color=never # getExtensionByLanguage 메서드 정의 검색 rg -n "getExtensionByLanguage" --color=neversrc/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java (3)
52-52: GitHubPushService로의 의존성 변경이 적절합니다.기존
GitHubService에서 새로운GitHubPushService로의 의존성 변경이 올바르게 수행되었습니다.
71-71: 메서드명 변경이 더 명확한 의미를 전달합니다.
submitCodeStream에서processSubmissionAsync로의 변경이 메서드의 실제 기능을 더 잘 표현합니다.
80-80: 새로운 서비스 호출이 올바르게 구현되었습니다.
gitHubPushService.pushSolutionToRepo(ctx)호출이 리팩터링된 서비스 구조와 일치합니다.src/main/java/org/ezcode/codetest/infrastructure/github/model/PushStatus.java (1)
8-17: 푸시 상태 enum이 깔끔하게 구현되었습니다.한국어 메시지와 함께 명확한 상태 정의가 이루어져 있으며, Lombok을 활용한 간결한 코드 구성이 좋습니다.
src/main/java/org/ezcode/codetest/application/submission/dto/event/GitPushStatusEvent.java (1)
5-23: 이벤트 레코드가 우수한 설계로 구현되었습니다.불변 record 구조와 편의성을 위한 정적 팩토리 메서드들이 잘 구현되어 있습니다. 코드가 간결하고 의도가 명확합니다.
src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java (1)
153-159: 새로운 언어 정보 접근자 메서드들이 잘 구현되었습니다.
getLanguageName()과getLanguageVersion()메서드들은 GitHubPushRequest에서 언어 메타데이터를 제공하기 위해 적절히 추가되었습니다. 단순한 위임 패턴으로 구현되어 명확하고 직관적입니다.src/main/java/org/ezcode/codetest/infrastructure/event/dto/submission/response/GitPushStatusResponse.java (1)
5-13: 간결하고 목적이 명확한 DTO 레코드입니다.Git 푸시 상태 메시지를 캡슐화하는 단순하고 효과적인 구현입니다. PushStatus enum을 받는 편의 생성자도 잘 설계되었습니다.
src/main/java/org/ezcode/codetest/domain/submission/exception/GitHubClientException.java (1)
11-22: GitHub 클라이언트 전용 예외 클래스가 잘 설계되었습니다.BaseException을 적절히 확장하고 GitHubExceptionCode enum을 통해 일관된 예외 처리를 제공합니다. 모든 필수 필드가 생성자에서 올바르게 초기화되었습니다.
src/main/java/org/ezcode/codetest/application/submission/dto/request/github/GitHubPushRequest.java (3)
21-30: 새로운 필드들이 적절히 추가되었습니다.
difficulty,languageName,languageVersion필드들은 GitHub 푸시 메타데이터를 풍부하게 만들어 줍니다. 언어 정보는 파일 확장자 결정에도 활용될 것으로 보입니다.
40-57: 팩토리 메서드가 잘 개선되었습니다.
decryptedToken파라미터를 받도록 변경된 것은 보안 관점에서 좋은 개선입니다. 새로운 필드들도 SubmissionContext에서 적절히 추출하여 할당하고 있습니다.
59-61: 언어 정보 조합 메서드가 유용합니다.
getLanguage()메서드는 언어명과 버전을 간편하게 조합해서 반환하는 유틸리티 메서드로 잘 설계되었습니다.src/main/java/org/ezcode/codetest/infrastructure/github/GitHubClientImpl.java (3)
14-21: 의존성 주입 구조가 잘 설계되었습니다.각 컴포넌트의 역할이 명확하게 분리되어 있어 단일 책임 원칙을 잘 따르고 있습니다.
24-29: 소스 코드 변경 여부를 효율적으로 확인합니다.기존 blob SHA와 비교하여 불필요한 커밋을 방지하는 최적화가 잘 구현되었습니다.
36-38: 트리 변경 여부 확인으로 추가 최적화를 제공합니다.새로 생성된 트리가 기존 트리와 동일한 경우 커밋을 건너뛰는 로직이 우수합니다.
src/main/java/org/ezcode/codetest/infrastructure/github/GitHubContentBuilder.java (2)
68-87: Git 트리 엔트리 구성이 적절합니다.파일 경로, 모드, 타입, 컨텐츠 등이 GitHub API 요구사항에 맞게 구성되었습니다.
90-95: 타임스탬프 포맷팅이 사용자 친화적입니다.
yyyyMMddHHmmss형식을yyyy-MM-dd HH:mm:ss로 변환하여 가독성을 높였습니다.src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java (3)
26-29: 조건부 실행 로직이 명확합니다.Git 푸시가 필요하지 않거나 제출이 실패한 경우 조기 반환하는 것이 효율적입니다.
31-37: 이벤트 기반 상태 업데이트가 우수합니다.시작과 성공 이벤트를 발행하여 실시간 상태 추적이 가능하도록 구현했습니다.
38-41: 예외 처리 및 알림 구조가 포괄적입니다.예외 발생 시 알림과 실패 이벤트를 모두 처리하여 관찰 가능성을 높였습니다.
src/main/java/org/ezcode/codetest/infrastructure/event/publisher/StompMessageService.java (2)
26-26: 토픽 접두사를 중앙집권화하여 유지보수성을 향상시켰습니다.
SUBMISSION_DEST_PREFIX상수 도입으로 일관된 메시징 목적지 관리가 가능해졌습니다.
110-116: Git 상태 메시징 기능이 기존 패턴과 일관성 있게 구현되었습니다.새로운
sendGitStatus메서드가 다른 메시징 메서드와 동일한 구조를 따르고 있습니다.src/main/java/org/ezcode/codetest/domain/submission/exception/code/GitHubExceptionCode.java (2)
13-28: GitHub API 에러 시나리오를 포괄적으로 다룹니다.인증, 권한, 리소스 없음, 서버 오류, 속도 제한, 네트워크 오류 등 주요 에러 케이스가 잘 정의되었습니다. 한국어 메시지도 사용자 친화적으로 작성되었습니다.
30-32: ResponseCode 인터페이스 구현이 적절합니다.
success,status,message필드가 예외 처리 시스템과 일관성 있게 구성되었습니다.
| return Objects.requireNonNull(ref) | ||
| .get("object") | ||
| .get("sha") | ||
| .asText(); | ||
| } |
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.
JSON 파싱 시 null 안전성 개선 필요
중첩된 JSON 노드 접근 시 중간 노드가 null일 경우 NPE가 발생할 수 있습니다. 보다 안전한 접근 방법을 사용하세요.
- return Objects.requireNonNull(ref)
- .get("object")
- .get("sha")
- .asText();
+ JsonNode objectNode = Objects.requireNonNull(ref).get("object");
+ if (objectNode == null || !objectNode.has("sha")) {
+ throw new GitHubClientException(GitHubExceptionCode.INVALID_RESPONSE);
+ }
+ return objectNode.get("sha").asText();이 패턴은 fetchBaseTreeSha와 createCommit 메서드에도 동일하게 적용되어야 합니다.
Also applies to: 150-154, 183-184
🤖 Prompt for AI Agents
In src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java
around lines 130-134, 150-154, and 183-184, the current JSON parsing directly
accesses nested nodes without null checks, risking NullPointerExceptions if
intermediate nodes are null. Refactor these sections to safely navigate the JSON
structure by checking each node for null before accessing child nodes, using
conditional checks or Optional patterns to ensure null safety during JSON
parsing.
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 네, 확인해보시고 판단해주세요! JSON 파싱 부분의 null 안전성은 런타임 안정성에 도움이 될 수 있지만, 우선순위에 따라 결정하시면 됩니다.
🧠 Learnings used
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: 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.
| "message", String.format("문제 %s. %s (%s) – 메모리: %sKB, 시간: %sms", | ||
| req.problemId(), | ||
| req.problemTitle(), | ||
| req.difficulty(), | ||
| req.averageMemoryUsage(), | ||
| req.averageExecutionTime() | ||
| ), |
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
커밋 메시지 국제화 및 설정 관리 필요
커밋 메시지가 한국어로 하드코딩되어 있어 국제 사용자에게는 적절하지 않을 수 있습니다. 메시지 포맷을 설정 파일로 관리하거나 사용자 언어 설정에 따라 변경할 수 있도록 개선하세요.
- "message", String.format("문제 %s. %s (%s) – 메모리: %sKB, 시간: %sms",
+ "message", messageFormatter.format(req),Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java
around lines 159 to 165, the commit message is hardcoded in Korean, which is not
suitable for international users. Refactor the code to externalize the message
format into a configuration or resource file and implement logic to select the
message language based on user locale or language settings, ensuring the message
is dynamically localized instead of hardcoded.
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 알겠습니다! 한국어 사용자만 대상으로 하는 서비스라면 현재 구현이 적절하네요. 실용적인 접근 방식이 맞다고 생각합니다.
(\ /)
( ..)
o(")(")
✏️ Learnings added
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.654Z
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.
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#111
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:58-73
Timestamp: 2025-06-27T09:53:52.351Z
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: 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.
| .onStatus(status -> status.value() == 422, resp -> | ||
| resp.bodyToMono(String.class) | ||
| .flatMap(errorBody -> Mono.error(new RuntimeException(errorBody))) | ||
| ) |
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.
예외 처리 일관성 개선 필요
422 상태 코드에 대해 RuntimeException을 던지는 것은 다른 에러 처리 패턴과 일치하지 않습니다. 다른 곳에서 사용하는 GitHubClientException을 사용하여 일관성을 유지하세요.
- resp.bodyToMono(String.class)
- .flatMap(errorBody -> Mono.error(new RuntimeException(errorBody)))
+ Mono.error(new GitHubClientException(GitHubExceptionCode.TREE_CREATION_FAILED))또한 에러 바디를 그대로 노출하는 것은 보안상 위험할 수 있으므로, 로깅은 하되 사용자에게는 일반적인 에러 메시지를 보여주는 것이 좋습니다.
🤖 Prompt for AI Agents
In src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java
around lines 93 to 96, replace the RuntimeException thrown for HTTP 422 status
with the custom GitHubClientException used elsewhere for consistency. Modify the
error handling to log the detailed error body internally but throw a
GitHubClientException with a generic user-friendly message instead of exposing
the raw error body directly.
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 이해했습니다! 디버깅할 때 에러 메시지가 숨겨져서 불편하셨군요.
앞으로 비슷한 상황에서는 GitHubClientException을 사용하면서도 디버깅을 위해 로깅을 추가하는 방법을 고려해보세요:
.onStatus(status -> status.value() == 422, resp ->
resp.bodyToMono(String.class)
.doOnNext(errorBody -> log.debug("GitHub API 422 error: {}", errorBody))
.flatMap(errorBody -> Mono.error(new GitHubClientException(GitHubExceptionCode.TREE_CREATION_FAILED)))
)이렇게 하면 일관성도 유지하면서 디버그 로그로 상세한 에러 내용도 확인할 수 있습니다!
✏️ Learnings added
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.910Z
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.
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#98
File: src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java:17-22
Timestamp: 2025-06-25T01:24:30.754Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
Learnt from: chat26666
PR: ezcode-my/backend#88
File: src/main/java/org/ezcode/codetest/application/game/play/GamePlayUseCase.java:0-0
Timestamp: 2025-06-21T21:29:21.785Z
Learning: JwtUtil.extractClaims() 메서드는 이미 JwtException을 catch하여 ServerException으로 변환하는 예외 처리가 구현되어 있으므로, 호출하는 곳에서 추가적인 try-catch 블록이 필요하지 않습니다.
Learnt from: chat26666
PR: ezcode-my/backend#64
File: src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/game/RandomEncounterRepositoryImpl.java:10-16
Timestamp: 2025-06-15T04:37:22.609Z
Learning: chat26666은 Repository 구현체를 만들 때 뼈대(skeleton)를 먼저 생성하고 나중에 메서드를 구현하는 개발 방식을 사용한다. 이런 경우 아직 미구현 상태인 것이 의도적인 것일 수 있다.
Learnt from: thezz9
PR: ezcode-my/backend#73
File: src/main/java/org/ezcode/codetest/infrastructure/openai/OpenAIReviewClient.java:52-64
Timestamp: 2025-06-18T11:42:03.701Z
Learning: OpenAI API 클라이언트에서는 두 가지 재시도 전략을 사용한다: 1) WebClient의 retryWhen은 네트워크/HTTP 에러 및 타임아웃에 대한 재시도, 2) 외부 for 루프는 API 응답 포맷 검증 실패에 대한 재시도. 이는 서로 다른 실패 상황을 처리하는 독립적인 메커니즘이다.
Learnt from: chat26666
PR: ezcode-my/backend#84
File: src/main/java/org/ezcode/codetest/domain/game/strategy/skill/skilldecorator/DefenceDecorator.java:43-64
Timestamp: 2025-06-20T09:27:41.998Z
Learning: DefenceDecorator에서 로그 메시지의 퍼센트 계산에 buff * 200을 사용하는 것은 의도된 설계입니다. 실제 적용되는 버프 값과 표시되는 퍼센트 값이 다르게 설계되었습니다.
Learnt from: chat26666
PR: ezcode-my/backend#84
File: src/main/java/org/ezcode/codetest/domain/game/strategy/skill/skilldecorator/PerfectAimDecorator.java:51-51
Timestamp: 2025-06-20T09:27:58.546Z
Learning: PerfectAimDecorator 클래스에서 로그 메시지의 `accBuff * 300` 계산은 의도적인 설계입니다. 명중률 표시에서 300을 곱하는 것은 올바른 구현이므로 100으로 변경을 제안하면 안 됩니다.
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:159-165
Timestamp: 2025-06-28T02:03:38.654Z
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: 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.
If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!
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 천만에요! 😊
.doOnNext()로 로깅하는 방법은 Reactor에서 사이드 이펙트를 처리하는 좋은 패턴이에요. 디버깅할 때 정말 유용하면서도 코드 일관성을 해치지 않죠.
다음에 비슷한 상황이 있으면 언제든 물어보세요!
🧠 Learnings used
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.910Z
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#114
File: src/main/java/org/ezcode/codetest/infrastructure/github/GitHubApiClient.java:159-165
Timestamp: 2025-06-28T02:03:38.654Z
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#98
File: src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java:17-22
Timestamp: 2025-06-25T01:24:30.754Z
Learning: JudgeClient에서 모든 예외를 SubmissionException으로 래핑해서 넘길 계획이므로, SubmissionErrorEvent.resolveCode() 메서드의 캐스팅은 안전할 예정임.
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.351Z
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#73
File: src/main/java/org/ezcode/codetest/infrastructure/openai/OpenAIReviewClient.java:52-64
Timestamp: 2025-06-18T11:42:03.701Z
Learning: OpenAI API 클라이언트에서는 두 가지 재시도 전략을 사용한다: 1) WebClient의 retryWhen은 네트워크/HTTP 에러 및 타임아웃에 대한 재시도, 2) 외부 for 루프는 API 응답 포맷 검증 실패에 대한 재시도. 이는 서로 다른 실패 상황을 처리하는 독립적인 메커니즘이다.
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: 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.
작업 내용
트러블 슈팅
해결해야 할 문제
참고 사항
Summary by CodeRabbit
신규 기능
버그 수정
리팩터링 및 개선
환경설정