Skip to content

Renewal 실행 결과를 기존 업무·안내 초안·생성 문서에 연결 - #131

Merged
krestar merged 11 commits into
mainfrom
feat/128-renewal-runtime
Aug 11, 2026
Merged

Renewal 실행 결과를 기존 업무·안내 초안·생성 문서에 연결#131
krestar merged 11 commits into
mainfrom
feat/128-renewal-runtime

Conversation

@hywznn

@hywznn hywznn commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

한눈에 보기

기존 Task를 AI Renewal Runtime에 연결하고, AI가 돌려준 누락 Slot·근로자 안내·생성 문서를 Server의 기존 업무와 문서함에 안전하게 반영합니다.

이번 갱신에서는 같은 EXPIRY_RENEWAL Intent에 속한 Workflow를 Task type별로 정확히 고정했습니다.

Task type canonical Workflow
RECONTRACT WF-CON-001
EMPLOYMENT_PERIOD_EXTENSION WF-CON-001
STAY_PERIOD_EXTENSION WF-STY-001

Closes #128
Closes #136

왜 필요한가요?

Server가 재계약·취업활동기간 연장·체류기간 연장 Task를 실제 Agent 실행 결과와 연결해야 합니다.
다만 AI 결과만으로 업무를 자동 승인하거나 발송하면 안 되므로, 기존 Task 상태·HR 검토·문서함 경계 안에서만 반영합니다.

기존 브랜치에는 Workflow 정합성 문제가 하나 있었습니다.

허용 Task type: RECONTRACT / STAY_PERIOD_EXTENSION / EMPLOYMENT_PERIOD_EXTENSION
검증 Workflow: 모든 Task를 WF-STY-001로 고정

이 상태에서는 RECONTRACT도 체류 연장 Workflow로 AI에 전달됩니다. Knowledge Catalog에서는 재계약과 취업활동기간 연장이 WF-CON-001이므로 실제 계약과 달랐습니다.

변경 후 실행 흐름

HR
  → POST /api/v1/tasks/{taskId}/renewal-run
  → Server: Task/Worker/Company/승인 OCR 조회
  → Server: Task type ↔ Workflow 쌍 검증
  → AI: POST /internal/v1/workflows/renewal/run
  → Server: request/attempt/task/Workflow와 응답 구조 재검증
  → 기존 Task·안내 초안·문서함에 결과 반영
  → HR 검토

자동 승인, 자동 발송, 기관 자동 제출, 자동 완료는 수행하지 않습니다.

API와 Context 구성

Client → Server

  • POST /api/v1/tasks/{taskId}/renewal-run
  • HR instruction과 expected_version 수용
  • 직전 AI 응답이 요구한 USER_INPUT Slot만 slot_answers로 수용
  • 여권번호·외국인등록번호 등 DOCUMENT_OCR Slot의 Client 직접 제출 차단

Server → AI

  • Endpoint: POST /internal/v1/workflows/renewal/run
  • Task, Worker, Company 스냅샷 전달
  • 연결된 문서와 승인된 최신 OCR 결과 전달
  • HR 입력 Slot은 business_data_json.renewal_inputs에 저장한 뒤 다음 호출의 slots에 병합
  • Bearer 인증, HTTP/1.1, timeout, 응답 크기 제한 적용

Task type과 Workflow 검증

RenewalWorkflowPolicy에서 Renewal Runtime이 지원하는 canonical 쌍을 한 곳에 정의합니다.

  • RECONTRACT → WF-CON-001
  • EMPLOYMENT_PERIOD_EXTENSION → WF-CON-001
  • STAY_PERIOD_EXTENSION → WF-STY-001

Server는 두 단계에서 검증합니다.

  1. Context 조회 시 Task type과 저장된 task.workflowId가 맞지 않으면 AI를 호출하지 않습니다.
  2. 정상 AI 응답의 workflowId가 요청의 task.workflowId와 다르면 UNEXPECTED_WORKFLOW로 거부합니다.

따라서 다음 교차 조합은 통과하지 않습니다.

  • RECONTRACT + WF-STY-001
  • EMPLOYMENT_PERIOD_EXTENSION + WF-STY-001
  • STAY_PERIOD_EXTENSION + WF-CON-001
  • Renewal 이외 Task/Workflow

scenario=out_of_scope, intent=OUT_OF_SCOPE인 정상 종료만 빈 workflowId를 허용합니다.

AI 응답 반영 범위

누락정보와 Case 신호

  • missingSlots, requestedFields, caseSignals를 계약 범위 안에서 검증
  • ask_hr 결과는 HR 입력 대기 상태로 반영
  • ask_worker 결과는 기존 DocumentRequestDraft에 HR 검토용 안내 초안으로 저장
  • languageAssistant 결과도 허용된 필드와 크기 안에서만 저장

생성 문서

  • scenario=generate일 때만 generatedDocuments[] 처리
  • AI가 반환한 template_id, format, values를 문서 생성 API에 전달
  • 생성된 HWP를 기존 FileStorage, stored_file, worker_document에 연결
  • 검토 전 초안이므로 submission_status=SUBMITTED
  • 자동 VERIFIED 처리하지 않음
  • 개인정보가 포함될 수 있는 values는 Task JSON·감사로그·외부 API 응답에 저장하지 않음

현재 허용 템플릿은 Renewal 초안 4종입니다. HWPX 응답 계약은 수용하지만 HWPX 직접 생성·변환은 후속 범위입니다.

계약 및 보안 검증

  • 응답 requestId, attemptId, taskId 일치
  • 늦게 도착한 다른 attempt 응답 차단
  • Intent와 요청 Task Workflow 일치
  • confidence 0..1 범위
  • scenario별 필수 payload 검증
  • 중복/미허용 missingSlots, requestedFields, caseSignals 거부
  • 생성 문서 template/format/value 구조와 크기 제한
  • 다른 사업장 Task 접근 차단
  • API Key, Bearer Token, 비밀번호 등 서비스 인증정보 차단
  • 발화문, Slot 실제 값, 실명, 연락처, 토큰, AI 원문 응답을 구조화 로그에 기록하지 않음

관측성

Server가 직접 소유하는 다음 구간의 성공·실패·소요시간을 구조화 로그로 남깁니다.

  • CONTEXT_LOAD
  • RENEWAL_RUNTIME_CALL
  • DOCUMENT_GENERATION
  • RESULT_APPLY
  • TOTAL

Server 로그의 request_id는 AI X-Request-Id와 동일하게 사용하고, 외부 HTTP 요청 ID는 http_request_id로 별도 기록합니다.

자동 테스트

시나리오 확인 내용
canonical Workflow 쌍 세 Task type의 올바른 Workflow 수용
교차 Workflow 쌍 잘못된 Task/Workflow 조합 거부
응답 Workflow 변경 AI가 Task Workflow를 바꾸면 거부
HTTP wire RECONTRACT Task가 WF-CON-001로 전달되고 같은 값으로 응답
HR 재입력 ask_hr → slot_answers → generate 재호출
OCR Slot 보호 Client 직접 제출 차단
근로자 안내 안내 초안 저장과 HR 검토 경계
문서 생성 실제 HWP 저장·Worker 문서함 연결
동시성 expected_version과 늦은 attempt 응답 차단
테넌트 다른 사업장 접근 차단
민감정보 저장·응답·로그 비노출

로컬 검증

./gradlew clean test
  • 전체 test cases: 531
  • failures: 0
  • errors: 0
  • 로컬 PostgreSQL 환경이 없어 PostgreSQL 전용 test cases 37 skip
  • Renewal 계약/HTTP/API 통합 테스트 별도 실행 성공
  • GitHub PostgreSQL CI: 532 tests 및 executable jar build 통과
  • CI 첫 실행은 이 diff와 무관한 기존 Approval 동시성 테스트가 1회 실패했고, 코드 변경 없이 같은 commit을 재실행해 통과
  • 신규 DB 테이블과 Flyway migration 없음

AI팀 연동 조건

Renewal 요청에는 이미 확정된 task.workflowId가 들어갑니다. AI Runtime은 Renewal 내부에서 발화만 다시 분류해 이 값을 다른 Workflow로 덮어쓰면 안 됩니다.

구체적으로 다음을 맞춰야 합니다.

  • task.workflowId=WF-CON-001이면 정상 응답도 workflowId=WF-CON-001
  • task.workflowId=WF-STY-001이면 정상 응답도 workflowId=WF-STY-001
  • Renewal Language/Intent Node가 필요하면 task.workflowId를 constraint로 사용
  • OUT_OF_SCOPE만 빈 Workflow 허용

현재 Server 자동 테스트는 이 계약을 고정했고, AI #33 head 35d92fa에도 Task Workflow 보존 구현과 회귀 테스트가 반영됐습니다. 실제 Server ↔ AI smoke test는 AI #33 병합·배포 후 진행합니다.

배포 전 Smoke Test

재계약

  1. RECONTRACT / WF-CON-001 Task 실행
  2. AI 요청 task.workflowId=WF-CON-001 확인
  3. AI 응답 intent=EXPIRY_RENEWAL, workflowId=WF-CON-001 확인
  4. ask_hr, ask_worker, generate 중 해당 결과가 기존 Task에 반영되는지 확인

체류기간 연장

  1. STAY_PERIOD_EXTENSION / WF-STY-001 Task 실행
  2. 요청·응답 모두 WF-STY-001인지 확인
  3. 다른 Workflow 응답이 Server에서 거부되는지 확인

문서 생성

  1. scenario=generate 응답 수신
  2. 실제 HWP 생성 성공
  3. stored_fileworker_document 연결 확인
  4. Client 응답과 로그에 문서 values/개인정보가 없는지 확인

완료 상태

  • Renewal Runtime 요청·응답 계약
  • Task·Worker·Company·승인 OCR Context 구성
  • Task type별 canonical Workflow 검증
  • AI 응답 Workflow 변경 차단
  • HR Slot 답변 검증·저장·재호출 연결
  • OCR 대상 Slot의 Client 직접 제출 차단
  • 근로자 안내 초안 저장
  • 실제 HWP 생성 파일 저장·문서함 연결
  • 구간별 구조화 로그
  • 자동 승인·자동 발송 방지
  • 전체 로컬 테스트 통과
  • 최신 push 기준 GitHub CI 통과
  • Server 로컬 HTTP wire·실제 HWP 저장 통합 검증
  • AI feat: Auth·Company 로그인 구현 및 DB 마이그레이션 정합성 보완 #33 로컬 BERT/A.X Intent·Workflow 실모델 smoke
  • AI #33에 task.workflowId 보존 구현 및 회귀 테스트 반영 (head 35d92fa)
  • 배포 환경 Server ↔ AI Renewal/HWP end-to-end smoke test

제외 범위

  • HWPX 직접 생성·HWP→HWPX 변환
  • Agent LangGraph Node별 로그
  • progressEvents 전체 저장
  • 자동 승인·자동 발송·기관 자동 제출
  • 신규 DB 테이블

@BcKmini

BcKmini commented Aug 11, 2026

Copy link
Copy Markdown
Member

client 쪽에서 참고 차 확인했습니다 — 완료 상태 체크리스트 보니 'HWP/HWPX 생성 파일 저장·문서함 연결'까지 다 끝나서 남은 건 배포 환경 Smoke Test뿐이네요. CI도 통과 확인했습니다. client는 이 PR 병합 대기 상태로 issue #311/draft PR #312 걸어뒀고(fowoco/client), 병합되면 바로 이어서 붙이겠습니다.

@BcKmini
BcKmini self-requested a review August 11, 2026 07:16
BcKmini
BcKmini previously approved these changes Aug 11, 2026

@BcKmini BcKmini left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

현준님 파이팅

@hywznn hywznn changed the title feat: Renewal 실행 결과를 기존 업무와 안내 초안에 연결 Renewal 실행 결과를 기존 업무·안내 초안·생성 문서에 연결 Aug 11, 2026
krestar
krestar previously approved these changes Aug 11, 2026

@krestar krestar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

전체적으로 확인했고, 현재 이슈 #128 범위에서 merge를 막아야 할 정도의 문제는 찾지 못해 Approve 합니다.

한 가지 non-blocking으로 확인하고 싶은 부분이 있습니다.

RenewalExecutionContextReader에서는 RECONTRACT, STAY_PERIOD_EXTENSION, EMPLOYMENT_PERIOD_EXTENSION 세 TaskType을 Renewal 실행 대상으로 허용하고 있는데, Workflow 검증은 WF-STY-001로 고정되어 있습니다.

이슈 #128의 사용자 흐름이 체류연장 Candidate를 기준으로 작성되어 있어서 이번 범위에서 WF-STY-001만 실행하는 의도라면 현재 구현도 이해됩니다.

@hywznn

hywznn commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Workflow 정합성 리뷰 반영

@krestar 님이 확인해 주신 RenewalExecutionContextReader의 TaskType 허용 범위와 WF-STY-001 고정 검증 불일치를 보완했습니다.

문제였던 상태

RECONTRACT
STAY_PERIOD_EXTENSION
EMPLOYMENT_PERIOD_EXTENSION
  → 모두 WF-STY-001만 허용

이 경우 Knowledge Catalog에서 WF-CON-001을 사용하는 재계약·취업활동기간 연장 Task가 체류기간 연장 Workflow로 전달됩니다.

변경한 기준

Task type 허용 Workflow
RECONTRACT WF-CON-001
EMPLOYMENT_PERIOD_EXTENSION WF-CON-001
STAY_PERIOD_EXTENSION WF-STY-001
  • RenewalWorkflowPolicy에 canonical 쌍을 한 곳으로 모았습니다.
  • Context 조회 단계에서 잘못된 Task/Workflow 쌍은 AI 호출 전에 차단합니다.
  • 정상 AI 응답의 workflowId는 요청의 task.workflowId와 반드시 같아야 합니다.
  • OUT_OF_SCOPE 종료만 기존 계약대로 빈 workflowId를 허용합니다.
  • WireMock과 API 통합 fixture의 RECONTRACTWF-CON-001로 수정했습니다.

방어되는 사례

  • RECONTRACT + WF-STY-001
  • EMPLOYMENT_PERIOD_EXTENSION + WF-STY-001
  • STAY_PERIOD_EXTENSION + WF-CON-001
  • AI가 요청 Task의 Workflow를 다른 Workflow로 바꿔 반환하는 경우

검증

  • Renewal 정책·Validator·HTTP·API 통합 테스트 통과
  • ./gradlew clean test: 531 test cases, failures 0, errors 0
  • 로컬 PostgreSQL 환경이 없어 PostgreSQL 전용 37 test cases skip
  • 반영 commit: 16e2afb

실제 AI 연동 시 남은 확인

Server는 이제 요청의 task.workflowId를 기준으로 엄격히 검증합니다. AI Renewal Runtime도 내부 Language/Intent 단계에서 이 값을 constraint로 사용하고, 정상 응답에서 같은 Workflow를 유지해야 합니다.

예를 들어 RECONTRACT / WF-CON-001 요청에 AI가 발화만 다시 보고 WF-STY-001을 반환하면 Server가 UNEXPECTED_WORKFLOW로 거부합니다. 이 부분은 AI 반영 후 배포 smoke test에서 확인하겠습니다.

@hywznn
hywznn marked this pull request as ready for review August 11, 2026 11:55
@hywznn

hywznn commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

AI #33 연동 상태에 따른 체크리스트 갱신

AI #33 최신 head 35d92fa를 Server #131의 Renewal 계약과 대조해 완료 상태를 갱신했습니다.

완료로 변경한 항목

  • AI Renewal Runtime이 Server의 task.workflowId를 classifier constraint로 사용
  • 정상 업무에서 Language/Intent 결과가 기존 Task Workflow를 덮어쓰지 않도록 Graph 경계에서 보존
  • 외부 Language Node가 다른 Workflow를 반환해도 Task Workflow 복원
  • OUT_OF_SCOPE 예외에서만 빈 workflowId 허용
  • 관련 AI 회귀 테스트 반영

따라서 Server와 AI 양쪽 코드 계약은 현재 다음 canonical pair로 일치합니다.

Task type Workflow
RECONTRACT WF-CON-001
EMPLOYMENT_PERIOD_EXTENSION WF-CON-001
STAY_PERIOD_EXTENSION WF-STY-001

아직 완료하지 않은 항목

Server #131의 코드·CI와 AI #33의 구현은 준비됐지만, 실제 프로세스 간 호출은 아직 수행하지 않았으므로 배포 smoke 항목은 체크하지 않았습니다.

AI 상세 반영: fowoco/ai#33 (comment)

@krestar
krestar merged commit b6cb2be into main Aug 11, 2026
4 of 5 checks passed
@krestar
krestar deleted the feat/128-renewal-runtime branch August 11, 2026 13:23

@BcKmini BcKmini left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

확인했습니다. 완료 체크리스트 다 되어 있고 CI도 통과
-완-

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

Labels

None yet

Projects

None yet

3 participants