목표
사용자가 자기소개서를 submit하면 생성된 COVER_LETTER_REVIEW Job이 커밋 이후 비동기로 실행되고, OpenAI 최초 첨삭 client 결과가 ReviewVersion으로 저장되도록 한다.
작업 범위
-
관련 요구사항/API:
- REQ-005
- REQ-006
- API-014 후속 내부 실행
- API-015 상태 조회 결과 변화
- 공개 API path/request/response 계약 변경 없음
-
포함할 것:
submit()에서 새 PENDING Job을 생성한 경우에만 after-commit async 이벤트 발행
- worker가 PENDING Job을 PROCESSING으로 전환하고 자기소개서/문항 snapshot으로
FirstReviewRequest 생성
- 외부
FirstReviewClient.review(...) 호출은 DB transaction 밖에서 수행
- 성공 시
ReviewVersionService.completeFirstReview(...)로 ReviewVersion과 문항별 결과 저장
- 실패 시 Job을
FAILED로 전환하고 CoverLetter.status를 REVIEW_FAILED로 전환
FirstReviewClientException.Reason.PROVIDER_ERROR는 LLM_PROVIDER_ERROR
FirstReviewClientException.Reason.OUTPUT_VALIDATION_FAILED는 LLM_OUTPUT_VALIDATION_FAILED
- 실제 OpenAI 호출 없이 fake
FirstReviewClient 기반 테스트 작성
docs/status.md, docs/api/cover-letters.md, docs/api/llm-jobs.md 갱신
-
제외할 것:
- 자동 재시도 1회
- scheduler polling
- API-016 SSE
- partial result 저장소
- API-017~019, API-024
- 키워드 분석/면접 Job 실행
완료 기준
테스트
-
Worker service test:
- PENDING 최초 첨삭 Job을 PROCESSING으로 전환하고
FirstReviewRequest를 올바르게 만든다.
- fake client 성공 결과를
ReviewVersionService.completeFirstReview(...) 경계로 전달한다.
- 성공 후
ReviewVersionQuestionResult가 문항 순서대로 저장된다.
- provider 예외 시 Job/CoverLetter 실패 상태가 저장된다.
- output validation 예외 시
LLM_OUTPUT_VALIDATION_FAILED가 저장된다.
-
Submit/event test:
- 새 Job 생성 시 after-commit 이벤트가 발행되어 worker가 호출된다.
- 이미 REVIEWING 상태에서 기존 Job을 반환할 때는 worker를 다시 호출하지 않는다.
-
Regression:
- 기존
CoverLetterServiceTest, LlmJobServiceTest, ReviewVersionServiceTest, OpenAiFirstReviewClientTest 유지 또는 갱신
참고
- worker trigger는 after-commit async 이벤트로 구현한다.
- 이번 이슈는 기능 연결을 우선하고 자동 재시도는 후속 이슈로 분리한다.
partialResult는 계속 null로 유지한다.
목표
사용자가 자기소개서를 submit하면 생성된
COVER_LETTER_REVIEWJob이 커밋 이후 비동기로 실행되고, OpenAI 최초 첨삭 client 결과가ReviewVersion으로 저장되도록 한다.작업 범위
관련 요구사항/API:
포함할 것:
submit()에서 새 PENDING Job을 생성한 경우에만 after-commit async 이벤트 발행FirstReviewRequest생성FirstReviewClient.review(...)호출은 DB transaction 밖에서 수행ReviewVersionService.completeFirstReview(...)로ReviewVersion과 문항별 결과 저장FAILED로 전환하고CoverLetter.status를REVIEW_FAILED로 전환FirstReviewClientException.Reason.PROVIDER_ERROR는LLM_PROVIDER_ERRORFirstReviewClientException.Reason.OUTPUT_VALIDATION_FAILED는LLM_OUTPUT_VALIDATION_FAILEDFirstReviewClient기반 테스트 작성docs/status.md,docs/api/cover-letters.md,docs/api/llm-jobs.md갱신제외할 것:
완료 기준
POST /cover-letters/{coverLetterId}/submit이 새 Job 생성 후 API 응답을 막지 않고 worker 실행을 예약한다.COMPLETED, CoverLetter는REVIEWED,latestReviewVersionId는 생성된 ReviewVersion ID가 된다.FAILED, CoverLetter는REVIEW_FAILED가 된다.error.code로 저장된다../gradlew test,./gradlew check,git diff --check가 통과한다.테스트
Worker service test:
FirstReviewRequest를 올바르게 만든다.ReviewVersionService.completeFirstReview(...)경계로 전달한다.ReviewVersionQuestionResult가 문항 순서대로 저장된다.LLM_OUTPUT_VALIDATION_FAILED가 저장된다.Submit/event test:
Regression:
CoverLetterServiceTest,LlmJobServiceTest,ReviewVersionServiceTest,OpenAiFirstReviewClientTest유지 또는 갱신참고
partialResult는 계속null로 유지한다.