Skip to content

[AI Run] 비동기 실행 상태·재시도·멱등성 구현 #24

Description

@hywznn

한 줄 목표

AI 분석을 Server DB에 남는 AiRun으로 관리하고, HR이 채택한 Candidate만 Case와 Task로 만드는 기능입니다.

쉽게 말하면: AI가 제안서를 만들고, 담당자가 선택한 제안만 실제 업무카드가 됩니다.

사용자 흐름

  1. POST /api/v1/ai-runs가 발화문을 저장하고 202 + aiRunId 반환
  2. Server가 [AI Integration] AiRuntimeClient·계약 검증·장애 격리 구현 #8 AiRuntimeClient로 PLAN 요청
  3. 필요한 DB Slot은 [AI Run][P0] Agent 요청 Slot 조회·재호출 오케스트레이션 구현 #74 Resolver가 조회하고 ANALYZE 재호출
  4. 누락정보가 있으면 HR이 answers API로 답변
  5. 검토할 Candidate가 준비되면 HR이 채택 또는 폐기
  6. 채택된 Candidate만 [Case][P0] Case·Workflow Snapshot·업무함 Projection 구현 #83 Case와 기존 연장 Task가 됨
  7. 승인·근로자 발송·외부 제출은 별도 기능으로 처리

현재 main에 구현됨

  • POST /api/v1/ai-runs
  • GET /api/v1/ai-runs/{aiRunId}
  • POST /api/v1/ai-runs/{aiRunId}/answers
  • AiRun·AiAttempt·Question·Candidate 저장
  • 생성 요청 Idempotency-Key와 payload 충돌 검사
  • PLAN → Slot 해결 → ANALYZE 재호출
  • tenant 권한·낙관적 버전·감사로그
  • Case 조회와 Workflow Snapshot 기반 — [Case][P0] Case·Workflow Snapshot·업무함 Projection 구현 #83

구현 PR: #82, #88

지금 먼저 구현할 MVP 범위

Candidate 결정 API

POST /api/v1/ai-runs/{aiRunId}/candidate-decisions

  • Header: Idempotency-Key
  • Body: expectedRunVersion, decisions[]
  • action: ACCEPT 또는 DISCARD
  • ACCEPT: Server가 업무 규칙을 다시 검증한 뒤 Case와 Task 생성
  • DISCARD: Candidate를 삭제하지 않고 결정 이력 보존
  • 같은 요청을 다시 보내도 Case·Task 중복 생성 금지

고정 데모 Task

EXPIRY_RENEWAL Candidate를 채택하면 새 Task 유형을 늘리지 않고 이미 정의된 다음 3개를 사용합니다.

  1. 재계약
  2. 취업활동기간 연장
  3. 체류기간 연장

전체 Intent 업무 유형 확장은 #85 M4/P1에서 처리합니다.

고정 데모의 Workflow 확장 규칙

현재 AI Runtime은 Candidate 하나에 workflowId 하나를 반환합니다. 반면 Server Catalog의 EXPIRY_RENEWAL은 두 Workflow와 세 Task 유형으로 구성됩니다.

detectedIntent = EXPIRY_RENEWAL
├─ WF-CON-001 → RECONTRACT, EMPLOYMENT_PERIOD_EXTENSION
└─ WF-STY-001 → STAY_PERIOD_EXTENSION

MVP에서는 HR이 EXPIRY_RENEWAL Candidate를 채택하면 Server가 WorkflowCatalog.findByIntent로 활성 Workflow를 조회하고 위 세 Task를 만듭니다.

  • AI의 workflowId는 대표·검증 정보로 보존
  • detectedIntent와 Candidate Workflow가 Catalog에서 연결되지 않으면 422
  • Workflow ID와 TaskType을 Controller나 if문에 하드코딩하지 않음
  • Catalog가 허용한 Workflow와 TaskType만 생성
  • 수동 Task 생성 경로를 세 번 단순 호출하지 않음
  • 복합 Case 전용 생성 서비스가 세 Task와 전체 Snapshot을 한 Transaction에서 저장

현재 JdbcTaskCaseRegistrar는 수동 Task 하나의 Snapshot만 만들기 때문에, Candidate 연결에서는 전체 단계 Snapshot을 받는 별도 Port 또는 복합 등록 메서드가 필요합니다.

MVP 완료 조건

  • CandidateDecision 저장 구조와 Repository
  • ACCEPT 또는 DISCARD 권한·상태·expectedRunVersion 검증
  • Candidate 채택 시 [Case][P0] Case·Workflow Snapshot·업무함 Projection 구현 #83 Case와 3개 연장 Task를 한 Transaction에서 생성
  • 같은 Idempotency-Key 재전송 시 동일 결과 반환
  • 다른 payload에 같은 key 사용 시 409
  • 일부 Candidate만 선택 가능하고 선택되지 않은 후보는 자동 승인하지 않음
  • 감사로그에 결정자·시각·결과·생성된 caseId/taskIds 기록
  • 정상·중복·버전 충돌·타 사업장 접근 통합 테스트
  • OpenAPI 요청·응답·409/422 예시

후속 안정화 범위

MVP Candidate 연결 후 이어서 처리합니다.

상태 구분

종류 예시 의미
AiRun status RUNNING, SUCCEEDED, FAILED Server 실행 상태
analysisOutcome NEEDS_INFO, REVIEW_REQUIRED HR의 다음 행동
Task status DRAFT, READY_FOR_REVIEW 생성된 업무 상태

누락정보나 모호성은 기술 실패가 아닙니다. Candidate 채택도 승인이나 발송이 아닙니다.

작업 경계

Metadata

Metadata

Assignees

Labels

area:ai-integrationServer ↔ AI Runtime 내부 계약·Client·검증·trace 연동 영역; Prompt·모델·Provider 구현은 ai 저장소 소유area:serverSpring Boot API·도메인·DB·tenant·Task Workflow 영역; Prompt·모델·Provider 구현 제외priority:P0MVP 진행을 막는 최우선 핵심 작업security:privacy개인정보·접근권한·토큰·보안 영향이 있는 작업status:in-progress담당자가 현재 구현 중인 작업type:feature사용자 또는 Agent가 사용하는 기능 개발

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions