Repository navigation
feat: 면접에 기업을 골라 재작성·꼬리질문·피드백에 기업 정보를 싣게 함 - #97
Merged
Merged
Conversation
기업 맞춤 면접 1단계 API(명세 04-api v2). 기업 데이터는 시드 마이그레이션이 아니라
기동할 때 데이터 패키지(JSON)를 읽어 반영한다. 위치를 비우면 기업이 0개라 운영 화면은 그대로다.
- V34: company·company_source·company_fact, interview.company_id·company_snapshot, feedback.company_fit
- CompanyDataImporter: COMPANY_DATA_LOCATION의 *.json을 파일 검증(01 §3 규칙 1~7, 9)·묶음 유일성 확인 후
기업 하나 = 트랜잭션 하나로 반영. 내용 해시가 같으면 건너뛰고, 빠진 기업은 HIDDEN. 기동은 막지 않는다
- 샘플 기업 패키지 3개(company-data/sample), 운영용 자리(company-data/prod)
- GET /api/companies: 이름·법인명·별칭 검색(공백·대소문자 무시), 분류 필터, 분류 순서 → 이름순
- 면접 생성: companyId(선택)가 있으면 공개 기업을 스냅샷으로 저장. 숨김·없는 기업은 404
- 재작성(1:1·다대일)·피드백 요청에 company 스냅샷, Chat 준비 요청에 company {displayName, interviewerBrief}.
기업이 없으면 키 자체를 보내지 않는다
- 피드백 콜백 companyFit 저장(모양이 틀리면 비우고 피드백은 저장), 피드백·면접 응답에 company
A-1 P-2보다 먼저 main 위에서 만들었다. QuestionTailorService 변경은 빌더 두 줄이다.
기존 테스트는 생성자 인자 수만 맞췄다(null 추가).
배포는 Analysis → Chat → API → Web 순서다. 먼저 배포하면 기업 정보가 조용히 빠진다.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danjee2009
reviewed
Oct 15, 2026
danjee2009
left a comment
Member
There was a problem hiding this comment.
검토 범위: 기업 스냅샷을 Analysis 및 Chat 요청으로 전달하는 API 변경과 소비자 호환성을 확인했습니다. GitHub CI의 테스트 체크는 통과했습니다.
공개 기업이 없으면 면접에 기업을 고를 수 없어 company가 나가지 않는다. 분석·채팅 서버는 모르는 필드를 조용히 버리므로, COMPANY_DATA_LOCATION이 기업 기능의 배포 스위치라는 점을 설정 옆에 남긴다(PR #97 리뷰). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2-dayeon
approved these changes
Oct 15, 2026
# Conflicts: # src/main/java/repit/repit_api_server/domain/userdata/question/service/QuestionTailorService.java
- 스냅샷: 분석 서버 필수 구성(TALENT·BUSINESS 1개 이상, 빈 이름·요약·title·content 없음)을 면접 생성 전에 확인한다. 고정된 스냅샷이라 어긴 채 만든 면접은 영영 시작하지 못한다. 기업 행과 fact는 REPEATABLE READ로 같은 시점을 읽는다 - 가져오기: 웹 서버가 요청을 받기 전에 끝내도록 ApplicationRunner 대신 SmartInitializingSingleton에서 돈다 - 가져오기: 숨김을 반영보다 먼저 하고, 숨긴 기업이 들고 있던 DART 고유번호·사업자등록번호를 이번 묶음이 쓰면 놓게 한다. 반영에 실패한 기업은 나머지를 반영한 뒤 한 번 더 해, 묶음 안에서 식별자를 옮겨도 처리 순서와 상관없이 들어간다 - 모회사 파일이 묶음에 있는데 실패했으면 자회사의 기존 모회사 연결을 그대로 둔다. 묶음에서 빠졌을 때만 끊는다 - 검증: parentCode가 자기 code면 오류, review.reviewedBy 50자 상한 - 검색: NBSP·전각 공백도 무시((?U)\s), 숨긴 모회사 이름은 내보내지 않음, 모회사를 함께 읽어 N+1 제거(@EntityGraph) - 배지 id는 스냅샷 문자열 대신 interview.company_id 컬럼에서 받는다 - 테스트: 샘플 복사본(test resources)을 지우고 main 샘플을 직접 쓴다. 실제 트랜잭션 경계로 기업별 롤백·식별자 이동을 확인하는 CompanyDataImporterIsolationTest를 추가한다 목록 조회가 스냅샷 jsonb를 함께 읽는 문제는 저장 구조(interview.company_snapshot)를 바꿔야 해 이번에는 두었다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
개요
기업 맞춤 면접 구현 명세 04-api v2(1단계)입니다. main(bd6663e) 기준입니다. 공통 계약은 00-overview §6, 데이터 형식은 01-company-data를 따릅니다.
면접을 만들 때 기업 하나를 고를 수 있습니다. 고른 기업 정보는 면접에 스냅샷으로 남습니다. 이 스냅샷이 질문 재작성(1:1·다대일), Chat 꼬리질문, 피드백의
companyFit에 실립니다. 점수는 바뀌지 않습니다.기업 데이터는 시드 마이그레이션으로 넣지 않습니다. API가 기동할 때 데이터 패키지(JSON)를 읽어 반영합니다.
COMPANY_DATA_LOCATION을 비우면 기업이 0개입니다. 그러면 Web이 기업 선택 섹션을 숨기므로, 운영에 먼저 배포해도 화면은 지금과 같습니다.변경
1. 스키마 (
V34__add_company.sql)company,company_source,company_fact.interview.company_id·company_snapshot(jsonb),feedback.company_fit(jsonb).HIDDEN으로만 바꿉니다.2. 기업 데이터 가져오기 (
domain/company/importer)CompanyDataImporter가app.company.data-location의*.json을 읽습니다. 웹 서버가 요청을 받기 전에 끝나도록SmartInitializingSingleton에서 돕니다. 명세의ApplicationRunner는 내장 서버가 뜬 뒤에 돌아, 그 사이 요청이 반쯤 반영된 데이터를 볼 수 있습니다.CompanyDataValidator, 01 §3 규칙 1~7, 9)과 묶음 유일성(규칙 8)을 확인합니다.기업 데이터 가져오기: 새로 n, 갱신 u, 그대로 s, 숨김 h, 건너뜀 ecompany-data/sample/: 샘플 기업 3개(01 §5 문장 그대로)company-data/prod/: 실제 데이터 자리(.gitkeep)CompanyLimits한 곳에 모았습니다. 글자 수는 분석 서버(Python)와 맞춰 코드포인트로 셉니다.3.
GET /api/companies?q=&category=talentKeywords는 TALENT fact의title을 최대 3개 담습니다.legalSize가 미확인이면null입니다.4. 면접 생성과 전달
CreateInterviewRequest.companyId는 선택입니다. 있으면CompanySnapshotFactory가 공개 기업을 스냅샷으로 만들어 저장합니다(1:1·다대일). 숨긴 기업이나 없는 기업이면 404입니다.QuestionTailorRequest·QuestionTailorMultiRequest)과 피드백 요청(FeedbackSoloRequest·FeedbackMultiRequest)에company스냅샷을 그대로 싣습니다.company { displayName, interviewerBrief }만 싣습니다.company키를 아예 보내지 않습니다(@JsonInclude(NON_NULL)).companyFit은CompanyFitReader가 읽습니다. 모양이 틀리면 warn을 남기고 비우며, 피드백은 그대로 저장합니다.InterviewResponse에company { companyId, displayName } | null을 추가했습니다(생성·단건·목록).FeedbackResponse에company와companyFit을 추가했습니다.외부에서 보이는 동작 변화
GET /api/companies[]POST /api/interviews/create,companyId없음company: null)POST /api/interviews/create, 공개 기업companyIdcompanyPOST /api/interviews/create, 숨김·없는 기업company키 없음)배포 순서 (중요)
00 §7: Analysis → Chat → API → Web.
ignoreUnknown입니다.COMPANY_DATA_LOCATION을 넣지 않으면 기업이 0개입니다. 개발·스테이징은classpath:company-data/sample/*.json입니다.테스트
./gradlew test전체 682개가 통과했습니다(신규 66개).새로 3, 갱신 0, 그대로 0, 숨김 0, 건너뜀 0이었습니다.CompanyDataValidatorTest: 규칙별 위반 1건씩, 샘플 3개 오류 없음.CompanyDataImporterTest(@SpringBootTest, 롤백, 실제 배포되는company-data/sample을 복사해 사용)fact_id새로), 빠진 파일 숨김·복귀code중복 둘 다 건너뜀, 위치 비움·파일 0개CompanyDataImporterIsolationTest(@SpringBootTest, 실제 트랜잭션 경계): 한 기업의 DB 오류는 그 기업만 건너뜁니다. 묶음 안에서 옮긴 DART 고유번호, 숨긴 기업에서 넘겨받는 식별자도 확인합니다.CompanySnapshotFactoryTest,CompanyQueryServiceTestFeedbackServiceCompanyTest(@SpringBootTest): 요청에company,companyFitjsonb 저장·조회, null·형식 오류.InterviewServiceCreateTest: SOLO·MULTI 스냅샷, 기업 없음, 404.QuestionTailorServiceRequestTest: solo·multicompany, 기업 없으면 키 없음.ChatInterviewHandoffServiceTest: 기업 요약 두 칸만, 기업 없으면 키 없음.참고
/api/interviews/getAll, 피드백 목록)는 배지 하나를 만들려고company_snapshotjsonb를 함께 읽습니다. 빼려면 저장 구조를 별도 테이블이나 지연 로딩으로 바꿔야 해서 이번에는 두었습니다. 면접당 수 KB 수준입니다.QuestionTailorService요청 빌더 두 곳뿐이었습니다. 두 곳 모두.company(...)와 P-2의withTailorId(...)콜백 주소를 함께 남겼습니다. 병합 결과로 전체 701개 테스트가 통과했습니다. 리뷰 반영(71faefb) 뒤 전체 711개가 통과합니다.null추가). 대상은CreateInterviewRequest,FeedbackCallbackRequest.Result,InterviewService입니다. 단언문은 바꾸지 않았습니다.<code>.json)도 "읽은 기업"으로 쳐서 그 기업을 숨기지 않습니다(§3-4-7 "검증에 실패한 파일의 기업은 기존 상태 유지").(company_id, source_key)유일 제약에 걸립니다.🤖 Generated with Claude Code