Skip to content

[✨Feat] 최초 첨삭 비동기 worker 구현 #48

Description

@yong203

목표

사용자가 자기소개서를 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.statusREVIEW_FAILED로 전환
    • FirstReviewClientException.Reason.PROVIDER_ERRORLLM_PROVIDER_ERROR
    • FirstReviewClientException.Reason.OUTPUT_VALIDATION_FAILEDLLM_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 실행

완료 기준

  • POST /cover-letters/{coverLetterId}/submit이 새 Job 생성 후 API 응답을 막지 않고 worker 실행을 예약한다.
  • worker 성공 시 Job은 COMPLETED, CoverLetter는 REVIEWED, latestReviewVersionId는 생성된 ReviewVersion ID가 된다.
  • worker 실패 시 Job은 FAILED, CoverLetter는 REVIEW_FAILED가 된다.
  • provider 실패와 출력 검증 실패가 서로 다른 error.code로 저장된다.
  • 중복 submit으로 기존 진행 중 Job을 반환하는 경우 worker를 중복 예약하지 않는다.
  • 실제 OpenAI API key 없이 모든 자동 테스트가 통과한다.
  • ./gradlew test, ./gradlew check, git diff --check가 통과한다.

테스트

  • 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로 유지한다.

Metadata

Metadata

Assignees

Labels

✨ Feature새로운 기능 구현

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions