Skip to content

prod 배포#325

Merged
unifolio0 merged 12 commits intomainfrom
develop
Jan 31, 2026
Merged

prod 배포#325
unifolio0 merged 12 commits intomainfrom
develop

Conversation

@unifolio0
Copy link
Contributor

closed #

작업 내용

스크린샷

참고 사항

@unifolio0 unifolio0 self-assigned this Jan 31, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 31, 2026

Caution

Review failed

The pull request is closed.

Summary by CodeRabbit

릴리스 노트

새 기능

  • 이력서 기반 면접 생성: 이력서를 업로드하여 맞춤형 면접 질문 자동 생성
  • 면접 질문 상태 추적: 생성 진행률 확인 및 완료된 질문 조회
  • 통합 로그아웃/탈퇴: 제공업체별 인증 방식 단순화

버그 수정

  • 음성 모드 면접에서 URL 조회 개선
  • API 상태 코드 처리 정상화

주요 변경사항

  • 이전 면접 진행 엔드포인트 제거
  • 기존 평가 및 업로드 기능 통합 정리
  • 순위 조회 버전 3 제거

35-100 단어 범위

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

코드 리뷰 요약

Walkthrough

이 PR은 면접 시스템을 이력서 기반 질문 생성 방식으로 재설계합니다. 기존의 Bedrock/GPT 기반 진행 흐름을 제거하고, 새로운 이력서 기반 면접 기능을 도입합니다. Kakao 특화 인증 엔드포인트도 통합 엔드포인트로 변경되며, 여러 레거시 컴포넌트(BedrockClient, KafkaTemplate)가 삭제됩니다.

Changes

Cohort / File(s) Summary
인증 및 로그아웃 통합
api/src/main/java/com/samhap/kokomen/auth/controller/AuthController.java, api/src/main/java/com/samhap/kokomen/auth/service/AuthService.java
Kakao 특화 로그아웃/탈퇴 엔드포인트 제거 후 통합 엔드포인트(POST /logout, DELETE /withdraw)로 대체. 소셜 로그인 제공자 반복 처리로 일반화됨.
OAuth 클라이언트 리팩토링
api/src/main/java/com/samhap/kokomen/auth/external/GoogleOAuthClient.java, api/src/main/java/com/samhap/kokomen/auth/external/KakaoOAuthClient.java, api/src/main/java/com/samhap/kokomen/token/external/PaymentClientBuilder.java, api/src/main/java/com/samhap/kokomen/interview/external/SupertoneClientBuilder.java
lambda 기반 predicate를 method reference(::isInstance)로 변경. 기능적 동등성 유지.
기본 GPT 클라이언트 추상화
api/src/main/java/com/samhap/kokomen/global/external/BaseGptClient.java
RestClient 설정, 공통 요청/응답 처리, 에러 핸들링을 표준화한 새로운 추상 기본 클래스. 하위 클래스가 validateResponse() 구현 필요.
이력서 기반 질문 생성 - Bedrock 연동
api/src/main/java/com/samhap/kokomen/interview/external/ResumeBasedQuestionBedrockService.java
Bedrock Flow를 활용한 질문 생성 비동기 처리 및 GPT 폴백 로직. MDC 컨텍스트 관리와 streaming response 처리 포함.
이력서 기반 질문 생성 - GPT 클라이언트
api/src/main/java/com/samhap/kokomen/interview/external/ResumeBasedQuestionGptClient.java, api/src/main/java/com/samhap/kokomen/interview/external/dto/request/ResumeBasedQuestionGptRequest.java, api/src/main/java/com/samhap/kokomen/interview/external/dto/request/ResumeBasedQuestionGptMessage.java, api/src/main/java/com/samhap/kokomen/interview/external/dto/response/*
BaseGptClient 상속하여 이력서 기반 질문 생성 요청/응답 처리. 한글 시스템 프롬프트 및 JSON 파싱 포함.
이력서 기반 인터뷰 컨트롤러 및 서비스
api/src/main/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewController.java, api/src/main/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewService.java, api/src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationAsyncService.java, api/src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationStateService.java
질문 생성 요청, 상태 조회, 생성된 질문 목록 조회, 인터뷰 시작 기능 제공. 토큰 차감 및 비동기 처리 포함.
이력서 컨텐츠 추출 및 저장
api/src/main/java/com/samhap/kokomen/interview/service/ResumeContentService.java, api/src/main/java/com/samhap/kokomen/resume/service/PdfUploadService.java, api/src/main/java/com/samhap/kokomen/resume/domain/CareerMaterialsPathResolver.java
이력서/포트폴리오 텍스트 추출 및 캐싱. 멀티파트 기반에서 바이트 배열 기반으로 변경. CDN 경로 생성 간소화.
인터뷰 시스템 도메인 확장
common/src/main/java/com/samhap/kokomen/interview/domain/Interview.java, common/src/main/java/com/samhap/kokomen/interview/domain/InterviewType.java, common/src/main/java/com/samhap/kokomen/interview/domain/GeneratedQuestion.java, common/src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGeneration.java, common/src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGenerationState.java
Interview에 InterviewType, GeneratedQuestion 관계 추가. 새로운 ResumeQuestionGeneration 및 GeneratedQuestion 엔티티 정의. isResumeBased(), getDisplayCategory(), getDisplayQuestion() 헬퍼 메서드 추가.
인터뷰 팩사드 및 서비스 리팩토링
api/src/main/java/com/samhap/kokomen/interview/service/InterviewFacadeService.java, api/src/main/java/com/samhap/kokomen/interview/service/InterviewService.java, api/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedBedrockFlowAsyncService.java
기존 proceed/bedrock 흐름 제거, 이력서 기반 인터뷰 시작 로직 추가. 음성 모드 시 GeneratedQuestion 기반 URL 해석. getReferenceAnswers() 추가로 이력서 기반 인터뷰는 참고 답변 미제공.
레거시 인터뷰 관련 제거
api/src/main/java/com/samhap/kokomen/interview/controller/InterviewController.java, api/src/main/java/com/samhap/kokomen/interview/external/BedrockClient.java, api/src/main/java/com/samhap/kokomen/interview/external/BedrockFlowAsyncClient.java, api/src/main/java/com/samhap/kokomen/interview/service/InterviewLikeEventProducer*.java, api/src/main/java/com/samhap/kokomen/global/config/KafkaProducerConfig.java
proceedInterview, likeInterviewKafka 엔드포인트 및 BedrockClient, Kafka 기반 like 이벤트 프로듀서 완전 삭제. KafkaProducerConfig도 제거.
Resume 평가 시스템 리팩토링
api/src/main/java/com/samhap/kokomen/resume/external/ResumeEvaluationGptClient.java, api/src/main/java/com/samhap/kokomen/resume/service/ResumeEvaluationAsyncService.java
ResumeGptClient를 ResumeEvaluationGptClient로 대체. BaseGptClient 상속 및 response 검증 강화.
Resume 업로드 및 평가 엔드포인트 제거
api/src/main/java/com/samhap/kokomen/resume/controller/CareerMaterialsController.java, api/src/main/java/com/samhap/kokomen/resume/controller/ResumeEvaluationController.java, api/src/main/java/com/samhap/kokomen/resume/service/CareerMaterialsFacadeService.java
POST /resumes 업로드 엔드포인트 및 전체 ResumeEvaluationController 제거. CareerMaterialsFacadeService에서 평가 관련 메서드 삭제.
상수 클래스 패턴 변경
api/src/main/java/com/samhap/kokomen/global/constant/AwsConstant.java
abstract에서 final로 변경, private 생성자 추가로 유틸리티 클래스 패턴 강화.
토큰 시스템 배치 소비
common/src/main/java/com/samhap/kokomen/token/domain/Token.java, common/src/main/java/com/samhap/kokomen/token/domain/TokenPurchase.java, common/src/main/java/com/samhap/kokomen/token/domain/TokenPurchaseState.java, api/src/main/java/com/samhap/kokomen/token/service/TokenFacadeService.java, api/src/main/java/com/samhap/kokomen/token/service/TokenPurchaseService.java, api/src/main/java/com/samhap/kokomen/token/service/TokenService.java
useTokens(count) 메서드 추가로 배치 토큰 소비 지원. 자유 토큰 우선 소비 후 유료 토큰 차감.
회원 관련 엔드포인트 제거
api/src/main/java/com/samhap/kokomen/member/controller/MemberController.java, api/src/main/java/com/samhap/kokomen/member/service/MemberService.java, common/src/main/java/com/samhap/kokomen/member/repository/MemberRepository.java
GET /ranking/v3 및 findRankingPageV3 메서드 완전 제거.
데이터베이스 마이그레이션
common/src/main/resources/db/migration/V33__*.sql, common/src/main/resources/db/migration/V34__*.sql, common/src/main/resources/db/migration/V35__*.sql, common/src/main/resources/db/migration/V36__*.sql, common/src/main/resources/db/migration/V37__*.sql, common/src/main/resources/db/migration/V38__*.sql
Interview 테이블에 generated_question_id, interview_type 추가. resume_question_generation, generated_question 테이블 신규 생성. 상태 ENUM 확장 및 정리.
테스트 인프라 업데이트
api/src/test/java/com/samhap/kokomen/global/BaseTest.java, api/src/test/java/com/samhap/kokomen/global/DocsTest.java, api/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewFixtureBuilder.java, api/src/test/java/com/samhap/kokomen/global/fixture/interview/ResumeQuestionGenerationFixtureBuilder.java
GptClient, BedrockClient, KafkaTemplate 모킹 제거. InterviewProceedGptClient, ResumeBasedQuestionGptClient, ResumeBasedQuestionBedrockService, QuestionGenerationAsyncService 모킹 추가. InterviewFixtureBuilder에 interviewType 빌더 메서드 추가.
테스트 케이스 추가
api/src/test/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewControllerTest.java, api/src/test/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewServiceTest.java
이력서 기반 인터뷰 컨트롤러 및 서비스 종합 테스트 스위트 신규 추가(979줄, 127줄).
레거시 테스트 제거
api/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerTest.java, api/src/test/java/com/samhap/kokomen/resume/controller/ResumeEvaluationControllerTest.java, api/src/test/java/com/samhap/kokomen/resume/controller/CareerMaterialsControllerTest.java, src/test/java/com/samhap/kokomen/answer/service/AnswerFacadeServiceTest.java, src/test/java/com/samhap/kokomen/answer/service/TestAnswerLikedEventListener.java
인터뷰 진행, Resume 평가, 업로드, 답변 좋아요 관련 테스트 및 리스너 제거.
문서화 및 기타
.github/workflows/cd-api-dev.yml, CLAUDE.md, api/src/docs/asciidoc/index.adoc, api/src/test/java/com/samhap/kokomen/recruit/schedular/RecruitmentScheduler.java
develop 브랜치만 트리거하도록 CI 수정. 문서 재구성. AsciiDoc에 이력서 기반 인터뷰 끝점 추가. 채용 스케줄러 @Scheduled 주석 처리.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • nak-honest
  • kargowild

Poem

🐰 새 방식의 면접이 피어나고,
이력서 기반 질문 흐름이 반짝이네!
Bedrock과 GPT가 함께 춤을 추며,
토큰은 묶음으로 척척 소비되고,
레거시는 안녕, 현대 설계는 만세! 🎉

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands and usage tips.

@unifolio0 unifolio0 merged commit 9296756 into main Jan 31, 2026
5 of 6 checks passed
@gemini-code-assist
Copy link

Summary of Changes

Hello @unifolio0, 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!

이 Pull Request는 이력서 및 포트폴리오를 활용한 AI 기반 면접 질문 생성 기능을 도입하고, LLM(대규모 언어 모델) 클라이언트 통합 방식을 개선하는 데 중점을 둡니다. 또한, 인증 및 토큰 사용 로직을 간소화하고, 전반적인 코드 구조를 리팩토링하여 시스템의 확장성과 안정성을 높였습니다.

Highlights

  • 이력서 기반 면접 질문 생성 기능 추가: 사용자의 이력서와 포트폴리오를 기반으로 AI가 맞춤형 면접 질문을 생성하는 기능이 도입되었습니다. 이는 비동기 처리되며, Bedrock과 GPT를 활용합니다.
  • LLM 클라이언트 리팩토링: 기존 Bedrock 및 GPT 클라이언트가 BaseGptClient를 상속받는 전문화된 클라이언트들로 재구성되어, 코드 재사용성과 유지보수성이 향상되었습니다. Bedrock 호출 실패 시 GPT로 자동 폴백하는 로직이 추가되었습니다.
  • Kafka 이벤트 처리 로직 제거: 인터뷰 좋아요 관련 Kafka 프로듀서 및 설정이 제거되어, 이벤트 처리 방식이 변경되었음을 나타냅니다.
  • 인증 및 토큰 사용 로직 개선: 소셜 로그인 관련 불필요한 엔드포인트가 제거되고, 여러 개의 토큰을 한 번에 사용할 수 있는 기능이 추가되어 토큰 관리의 유연성이 증대되었습니다.
  • 문서 및 테스트 코드 업데이트: 새로운 기능에 맞춰 API 문서(index.adoc)와 CLAUDE.md 파일이 업데이트되었으며, 관련 테스트 코드들이 추가 및 수정되었습니다.
  • 데이터베이스 마이그레이션: 이력서 기반 면접 기능 지원을 위한 여러 개의 Flyway 마이그레이션 스크립트가 추가되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory 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.

Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/cd-api-dev.yml
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize 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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. 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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


코드의 숲, 새 길이 열리니 이력서 따라 질문 피어나네 AI 지혜, 면접의 새 바람

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 이력서 기반 면접 기능 추가와 함께 전반적인 코드 리팩토링을 포함하는 규모가 큰 변경이네요. 고생 많으셨습니다! BaseGptClient와 같은 추상화를 통해 코드 중복을 줄이고 구조를 개선한 점이 인상적입니다.

한 가지 제안드리고 싶은 점은, 이번 PR에 포함된 데이터베이스 마이그레이션(V33-V38)처럼 기능 개발 중 스키마 설계가 여러 번 변경되는 경우, 최종적으로 병합하기 전에 관련 마이그레이션들을 하나의 파일로 합치는(squash) 것을 고려해보시면 좋을 것 같습니다. 이렇게 하면 마이그레이션 히스토리가 간결하게 유지되어 나중에 스키마를 파악하거나 문제를 추적하기 더 수월해집니다.

전반적으로 프로젝트의 확장성과 유지보수성을 크게 향상시키는 좋은 변경이라고 생각합니다.

private final RecruitmentDataService recruitmentDataService;

@Scheduled(cron = "0 0 3 * * *", zone = "Asia/Seoul")
// @Scheduled(cron = "0 0 3 * * *", zone = "Asia/Seoul")

Choose a reason for hiding this comment

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

high

채용 공고 수집을 위한 @Scheduled 어노테이션이 주석 처리되었습니다. 이번 배포에서 의도된 변경 사항인지 확인이 필요합니다. 만약 의도치 않은 변경이라면, 주석을 해제해야 채용 공고 데이터가 주기적으로 업데이트될 수 있습니다.

Comment on lines +194 to +199
if (cleaned.startsWith("\"") && cleaned.endsWith("\"")) {
String unwrapped = cleaned.substring(1, cleaned.length() - 1);
return unwrapped.replace("\\\"", "\"").replace("\\n", "\n");
}
return cleaned;
}

Choose a reason for hiding this comment

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

medium

LLM이 반환하는 JSON 문자열이 큰따옴표로 감싸여 있을 때, 수동으로 이스케이프 문자를 처리하는 것은 예상치 못한 이스케이프 시퀀스에 취약할 수 있습니다. ObjectMapper를 사용하여 파싱하는 것이 더 안전하고 견고합니다. objectMapper.readValue(cleaned, String.class)를 사용하면 JSON 문자열 리터럴을 올바르게 파싱하여 다양한 이스케이프 문자를 처리할 수 있습니다.

Suggested change
if (cleaned.startsWith("\"") && cleaned.endsWith("\"")) {
String unwrapped = cleaned.substring(1, cleaned.length() - 1);
return unwrapped.replace("\\\"", "\"").replace("\\n", "\n");
}
return cleaned;
}
if (cleaned.startsWith("\"") && cleaned.endsWith("\"")) {
try {
return objectMapper.readValue(cleaned, String.class);
} catch (JsonProcessingException e) {
log.error("JSON 문자열 파싱 실패: {}", cleaned, e);
throw new ExternalApiException("LLM 응답 파싱에 실패했습니다.", e);
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant