[FEAT] 라이브 코테#359
Conversation
|
Warning Review limit reached
More reviews will be available in 39 minutes and 37 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
Walkthrough
ChangesLive Coding Interview Feature
Sequence Diagram(s)sequenceDiagram
participant Client
participant InterviewStartFacadeService
participant RootQuestionService
participant RootQuestion
participant InterviewProceedBedrockClient
participant InterviewBedrockRequestFactory
Client->>InterviewStartFacadeService: startInterview(InterviewRequest includeLiveCoding=true)
InterviewStartFacadeService->>RootQuestionService: findNextRootQuestion(includeLiveCoding=true)
RootQuestionService-->>InterviewStartFacadeService: RootQuestion(CODE type)
InterviewStartFacadeService->>RootQuestion: isCode()
InterviewStartFacadeService->>InterviewStartFacadeService: validateModeSupportedForRootQuestion()
InterviewStartFacadeService->>InterviewStartFacadeService: resolveInterviewType() → LIVE_CODING
InterviewStartFacadeService->>RootQuestion: createInitialQuestionContent() → title+"\n\n"+content
InterviewStartFacadeService-->>Client: Interview(LIVE_CODING), Question(합성된 content)
Note over Client,InterviewBedrockRequestFactory: 이후 답변 제출 시
Client->>InterviewProceedBedrockClient: requestProceed(questionAndAnswers)
InterviewProceedBedrockClient->>InterviewBedrockRequestFactory: createProceedSystem(LIVE_CODING)
InterviewBedrockRequestFactory-->>InterviewProceedBedrockClient: CodingInterviewBedrockSystemMessageConstant 프롬프트
InterviewProceedBedrockClient-->>Client: BedrockConverseResponse
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 본 PR은 라이브 코딩 테스트 기능을 구현하기 위한 백엔드 인프라와 로직을 추가합니다. 기존의 카테고리 기반 면접과 병행하여 코딩 문제 타입(CODE)을 지원하도록 도메인 모델을 확장하고, AI 면접관이 코딩 테스트에 적합한 방식으로 피드백을 생성하도록 프롬프트 전략을 분리했습니다. 또한, 긴 코드 답변 저장을 위해 데이터베이스 필드 크기를 조정하고, 관련 테스트 코드를 추가하여 안정성을 확보했습니다. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. 코드의 바다를 헤엄치며, 질문의 꼬리를 물고 답하네. 라이브 코테의 긴장 속에서, 우리의 로직은 빛을 발하리. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a live coding test feature to the interview system. It adds a new LIVE_CODING interview type, supports code-type root questions with titles, and expands the content length limits for questions and answers. Additionally, it integrates specific system prompts and evaluation rubrics for coding interviews with Bedrock and GPT clients. The review feedback suggests adding validation to ensure that title is not null or blank when creating a code-type root question, and defensively checking the title in createInitialQuestionContent to avoid prepending a null string to the content.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| public static RootQuestion forCode(Category category, String title, String content) { | ||
| RootQuestion rootQuestion = new RootQuestion(); | ||
| rootQuestion.category = category; | ||
| rootQuestion.state = RootQuestionState.ACTIVE; | ||
| rootQuestion.questionType = RootQuestionType.CODE; | ||
| rootQuestion.title = title; | ||
| rootQuestion.content = content; | ||
| return rootQuestion; | ||
| } |
There was a problem hiding this comment.
CODE 타입의 루트 질문은 반드시 제목(title)이 존재해야 합니다. forCode 팩토리 메서드 호출 시 title이 null이거나 빈 값인지 검증하는 로직을 추가하여 올바르지 않은 상태의 객체가 생성되는 것을 방지하는 것이 좋습니다.
public static RootQuestion forCode(Category category, String title, String content) {
if (title == null || title.isBlank()) {
throw new IllegalArgumentException("코드 타입 질문은 제목(title)이 필수입니다.");
}
RootQuestion rootQuestion = new RootQuestion();
rootQuestion.category = category;
rootQuestion.state = RootQuestionState.ACTIVE;
rootQuestion.questionType = RootQuestionType.CODE;
rootQuestion.title = title;
rootQuestion.content = content;
return rootQuestion;
}| public String createInitialQuestionContent() { | ||
| if (questionType == RootQuestionType.CODE) { | ||
| return title + "\n\n" + content; | ||
| } | ||
| return content; | ||
| } |
There was a problem hiding this comment.
questionType이 CODE일 때 title이 null이거나 빈 문자열(blank)인 경우, title + "\n\n" + content 연산으로 인해 "null\n\n..."과 같이 비정상적인 문자열이 생성될 수 있습니다.
title이 유효한 경우에만 제목을 본문 앞에 추가하도록 방어적으로 코드를 개선하는 것이 좋습니다.
| public String createInitialQuestionContent() { | |
| if (questionType == RootQuestionType.CODE) { | |
| return title + "\n\n" + content; | |
| } | |
| return content; | |
| } | |
| public String createInitialQuestionContent() { | |
| if (questionType == RootQuestionType.CODE && title != null && !title.isBlank()) { | |
| return title + "\n\n" + content; | |
| } | |
| return content; | |
| } |
Test Results 54 files 54 suites 1m 26s ⏱️ Results for commit e7bcf85. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/samhap/kokomen/interview/domain/RootQuestion.java`:
- Around line 61-68: The forCode factory method does not validate that the title
and content parameters are non-null and non-blank before assigning them to the
RootQuestion entity, which violates entity-level validation requirements. Add
validation checks in the forCode method to ensure both title and content
parameters are not null and not blank, throwing an appropriate exception (such
as IllegalArgumentException) if either validation fails. This will prevent the
creation of CODE type RootQuestion instances with invalid or empty title and
content fields.
In
`@src/main/java/com/samhap/kokomen/interview/service/InterviewStartFacadeService.java`:
- Around line 64-65: The issue is that VOICE interview mode combined with
includeLiveCoding=true produces non-deterministic results because the root
question is randomly selected, and validation fails only when CODE type is
selected. Add proactive validation before calling findNextRootQuestionForMember
in InterviewStartFacadeService to block the problematic VOICE +
includeLiveCoding=true combination at the request level, or ensure that when
interviewMode is VOICE, only GENERAL type root questions are selected. This will
make the result deterministic by preventing the scenario where
validateModeSupportedForRootQuestion fails due to incompatible mode and root
question type combinations.
In
`@src/test/java/com/samhap/kokomen/interview/repository/RootQuestionRepositoryTest.java`:
- Around line 47-48: The current test cases for the repository methods only
validate RootQuestionType.GENERAL filtering, leaving the CODE type path untested
and vulnerable to regressions. Add new test cases for both
findFirstRootQuestionMemberNotReceivedByCategory and its corresponding findLast
method (likely findLastRootQuestionMemberNotReceivedByCategory) that filter by
RootQuestionType.CODE instead of GENERAL. Each test should verify that when CODE
type is used as the filter, only CODE type data is returned in the results. This
provides coverage for the newly added CODE path in the repository filter logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3ac1054d-3697-473d-a312-caaa91f4f4e1
📒 Files selected for processing (33)
src/main/java/com/samhap/kokomen/answer/domain/Answer.javasrc/main/java/com/samhap/kokomen/interview/domain/Interview.javasrc/main/java/com/samhap/kokomen/interview/domain/InterviewType.javasrc/main/java/com/samhap/kokomen/interview/domain/Question.javasrc/main/java/com/samhap/kokomen/interview/domain/RootQuestion.javasrc/main/java/com/samhap/kokomen/interview/domain/RootQuestionType.javasrc/main/java/com/samhap/kokomen/interview/external/AnswerFeedbackBedrockClient.javasrc/main/java/com/samhap/kokomen/interview/external/InterviewProceedBedrockClient.javasrc/main/java/com/samhap/kokomen/interview/external/dto/request/InterviewBedrockRequestFactory.javasrc/main/java/com/samhap/kokomen/interview/repository/RootQuestionRepository.javasrc/main/java/com/samhap/kokomen/interview/service/InterviewStartFacadeService.javasrc/main/java/com/samhap/kokomen/interview/service/core/InterviewService.javasrc/main/java/com/samhap/kokomen/interview/service/dto/AnswerRequestV2.javasrc/main/java/com/samhap/kokomen/interview/service/dto/InterviewRequest.javasrc/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionResponse.javasrc/main/java/com/samhap/kokomen/interview/service/question/RootQuestionService.javasrc/main/java/com/samhap/kokomen/interview/tool/CodingInterviewBedrockSystemMessageConstant.javasrc/main/java/com/samhap/kokomen/interview/tool/CodingInterviewPromptFragments.javasrc/main/java/com/samhap/kokomen/interview/tool/GptSystemMessageConstant.javasrc/main/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactory.javasrc/main/resources/db/migration/V49__add_live_coding_question_type_and_widen_content.sqlsrc/test/java/com/samhap/kokomen/global/fixture/interview/RootQuestionFixtureBuilder.javasrc/test/java/com/samhap/kokomen/interview/controller/InterviewControllerTest.javasrc/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV3Test.javasrc/test/java/com/samhap/kokomen/interview/docs/InterviewDocsTest.javasrc/test/java/com/samhap/kokomen/interview/domain/RootQuestionTest.javasrc/test/java/com/samhap/kokomen/interview/external/dto/request/InterviewBedrockRequestFactoryTest.javasrc/test/java/com/samhap/kokomen/interview/repository/AnswerRepositoryTest.javasrc/test/java/com/samhap/kokomen/interview/repository/RootQuestionRepositoryTest.javasrc/test/java/com/samhap/kokomen/interview/service/LiveCodingInterviewServiceTest.javasrc/test/java/com/samhap/kokomen/interview/service/core/InterviewServiceTest.javasrc/test/java/com/samhap/kokomen/interview/service/question/RootQuestionServiceTest.javasrc/test/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactoryTest.java
| public static RootQuestion forCode(Category category, String title, String content) { | ||
| RootQuestion rootQuestion = new RootQuestion(); | ||
| rootQuestion.category = category; | ||
| rootQuestion.state = RootQuestionState.ACTIVE; | ||
| rootQuestion.questionType = RootQuestionType.CODE; | ||
| rootQuestion.title = title; | ||
| rootQuestion.content = content; | ||
| return rootQuestion; |
There was a problem hiding this comment.
CODE 루트 질문 생성 시 제목/본문 유효성 검증이 필요합니다.
forCode(...)가 title/content의 null·blank를 허용해서 CODE 질문의 필수 의미가 깨질 수 있고, 이후 초기 질문 생성 시 비정상 문자열이 생성될 수 있습니다.
수정 제안
+import com.samhap.kokomen.global.exception.BadRequestException;
@@
public static RootQuestion forCode(Category category, String title, String content) {
+ validateCodeQuestion(title, content);
RootQuestion rootQuestion = new RootQuestion();
rootQuestion.category = category;
rootQuestion.state = RootQuestionState.ACTIVE;
rootQuestion.questionType = RootQuestionType.CODE;
rootQuestion.title = title;
rootQuestion.content = content;
return rootQuestion;
}
+
+ private static void validateCodeQuestion(String title, String content) {
+ if (title == null || title.isBlank()) {
+ throw new BadRequestException("코딩 문제 제목은 비어 있을 수 없습니다.");
+ }
+ if (content == null || content.isBlank()) {
+ throw new BadRequestException("코딩 문제 본문은 비어 있을 수 없습니다.");
+ }
+ }As per coding guidelines, "Use @Valid annotation in DTOs for validation, entity-level validation in constructors, business validation in service layer".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/samhap/kokomen/interview/domain/RootQuestion.java` around
lines 61 - 68, The forCode factory method does not validate that the title and
content parameters are non-null and non-blank before assigning them to the
RootQuestion entity, which violates entity-level validation requirements. Add
validation checks in the forCode method to ensure both title and content
parameters are not null and not blank, throwing an appropriate exception (such
as IllegalArgumentException) if either validation fails. This will prevent the
creation of CODE type RootQuestion instances with invalid or empty title and
content fields.
Source: Coding guidelines
closed #
작업 내용
스크린샷
참고 사항