From 4ac8dc2c2999e99b0a1bbac350ef08db40b38ff3 Mon Sep 17 00:00:00 2001 From: hywznn Date: Tue, 18 Aug 2026 11:06:05 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat(knowledge):=20=EC=9E=AC=EA=B3=84?= =?UTF-8?q?=EC=95=BD=20Golden=20Case=20=EA=B3=84=EC=95=BD=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/demo/expiry_renewal_golden.yaml | 82 +++++++++++ fowoco-knowledge/knowledge/manifest.yaml | 1 + .../knowledge/workflow_catalog.yaml | 132 +++++++++++++++++- .../schemas/workflow-catalog.schema.json | 101 +++++++++++++- .../src/fowoco_knowledge/repository.py | 9 ++ .../src/fowoco_knowledge/validation.py | 39 ++++++ fowoco-knowledge/tests/test_repository.py | 39 ++++++ 7 files changed, 401 insertions(+), 2 deletions(-) create mode 100644 fowoco-knowledge/data/demo/expiry_renewal_golden.yaml diff --git a/fowoco-knowledge/data/demo/expiry_renewal_golden.yaml b/fowoco-knowledge/data/demo/expiry_renewal_golden.yaml new file mode 100644 index 0000000..531f046 --- /dev/null +++ b/fowoco-knowledge/data/demo/expiry_renewal_golden.yaml @@ -0,0 +1,82 @@ +scenario_id: DEMO-EXPIRY-RENEWAL-001 +status: synthetic_demo +contains_real_personal_data: false +case_template_id: CASE-EXPIRY-RENEWAL-001 +intent: EXPIRY_RENEWAL +workflow_ids: [WF-CON-001, WF-DOC-001, WF-STY-001] + +company: + display_name: FOWOCO Demo Company + +worker: + worker_ref: 92000000-0000-0000-0000-000000000006 + display_name: 응웬반A + legal_name: NGUYEN VAN AN + nationality_code: VN + preferred_language: vi + work_status: ACTIVE + date_policy: Server 실행일을 기준으로 Seed에서 상대 날짜를 계산 + stay_expiry_days_from_seed_date: 45 + contract_end_days_from_seed_date: 180 + employment_permit_end_days_from_seed_date: null + employment_activity_end_days_from_seed_date: null + +request: + instruction: 응웬반A의 재계약과 취업활동기간·체류기간 연장을 준비해줘 + expected_intent: EXPIRY_RENEWAL + expected_primary_workflow_id: WF-STY-001 + +hr_answers: + target_completion_date: 실행 당일로부터 7일 뒤 + company_recontract_intent: true + monthly_wage_krw: 2500000 + daily_work_hours: 8 + job_description: 자동차 부품 조립 및 검사 + work_location: FOWOCO 제1공장 + accommodation_provided: true + accommodation_description: 사업장 제공 기숙사 + +worker_submission: + delivery_locale: vi + response_type: SLOT_ANSWERS_SUBMITTED + answers: + worker_continued_employment_intent: true + requested_documents: [ARC] + synthetic_fixture_names: + - 외국인등록증_앞면_응웬반A.png + +expected_case: + title: E-9 재계약·취업활동기간·체류기간 연장 + tasks: + - order: 1 + task_type: RECONTRACT + title: 재계약 의사와 근로조건 확정 + - order: 2 + task_type: DOCUMENT_REQUEST + title: 신분서류 보완 + conditional: 신분서류가 없거나 유효성을 확인하지 못한 경우에만 생성 + - order: 3 + task_type: EMPLOYMENT_PERIOD_EXTENSION + title: 취업활동기간 연장 준비 + depends_on: [RECONTRACT, DOCUMENT_REQUEST_IF_PRESENT] + - order: 4 + task_type: STAY_PERIOD_EXTENSION + title: 체류기간 연장 준비와 결과 추적 + depends_on: [EMPLOYMENT_PERIOD_EXTENSION, DOCUMENT_REQUEST_IF_PRESENT] + +expected_generated_documents: + - template_id: standard_labor_contract_v6 + display_name: 별지 제6호 표준근로계약서 초안 + requires_hr_review: true + - template_id: employment_period_extension_application + display_name: 취업활동기간 연장신청서 초안 + requires_hr_review: true + - template_id: integrated_application + display_name: 통합신청서 초안 + requires_hr_review: true + +guardrails: + automatic_external_submission: false + automatic_document_approval: false + automatic_worker_message_send: false + ocr_updates_worker_profile_automatically: false diff --git a/fowoco-knowledge/knowledge/manifest.yaml b/fowoco-knowledge/knowledge/manifest.yaml index e2334bc..e317e9d 100644 --- a/fowoco-knowledge/knowledge/manifest.yaml +++ b/fowoco-knowledge/knowledge/manifest.yaml @@ -37,6 +37,7 @@ datasets: intent_split_manifest: data/intent/splits/manifest.yaml catalog_e2e_manifest: data/evaluation/e2e_catalog_manifest.yaml catalog_e2e_gold_candidates: data/evaluation/e2e_catalog_cases.jsonl + demo_expiry_renewal: data/demo/expiry_renewal_golden.yaml review_policy: minimum_reviewers_for_official_knowledge: 2 all_outbound_messages_require_hr_approval: true diff --git a/fowoco-knowledge/knowledge/workflow_catalog.yaml b/fowoco-knowledge/knowledge/workflow_catalog.yaml index 33c075d..1aa08e3 100644 --- a/fowoco-knowledge/knowledge/workflow_catalog.yaml +++ b/fowoco-knowledge/knowledge/workflow_catalog.yaml @@ -1,4 +1,4 @@ -version: 0.1.0 +version: 0.2.0 policy: state_model: [DRAFT, NEEDS_INFO, READY_FOR_REVIEW, APPROVED, IN_PROGRESS, WAITING_WORKER, WAITING_EXTERNAL, COMPLETED, CANCELLED] all_external_actions_require_human: true @@ -384,3 +384,133 @@ workflows: action: 회사 정책에 따른 채널로 전달 output: delivery_record completion_evidence: [approved_certificate_id, delivery_record] + +case_templates: + - id: CASE-EXPIRY-RENEWAL-001 + name: E-9 재계약·취업활동기간·체류기간 연장 + intent: EXPIRY_RENEWAL + workflow_ids: [WF-CON-001, WF-DOC-001, WF-STY-001] + tasks: + - key: recontract + order: 1 + task_type: RECONTRACT + workflow_id: WF-CON-001 + title: 재계약 의사와 근로조건 확정 + description: 회사와 근로자의 재계약 의사, 네 가지 기준일, 변경 근로조건을 확인하고 표준근로계약서 초안을 검토합니다. + activation: + mode: ALWAYS + depends_on: [] + depends_on_if_present: [] + checklist_items: + - item_code: COMPANY_RECONTRACT_INTENT_CONFIRMED + label: 회사의 재계약 의사 확인 + required: true + - item_code: WORKER_CONTINUED_EMPLOYMENT_INTENT_CONFIRMED + label: 근로자의 계속 근무 의사 확인 + required: true + - item_code: FOUR_KEY_DATES_VERIFIED + label: 계약 시작일·계약 종료일·취업활동기간 만료일·체류기간 만료일 확인 + required: true + - item_code: CHANGED_EMPLOYMENT_CONDITIONS_CONFIRMED + label: 임금·근무시간·업무·근무지·숙소 변경조건 확인 + required: true + - item_code: CURRENT_STANDARD_CONTRACT_DRAFT_REVIEWED + label: 최신 표준근로계약서 초안 검토 + required: true + - item_code: SIGNED_CONTRACT_STORED + label: 당사자 서명본 보관 + required: true + completion_evidence: + - company_intent + - worker_intent + - confirmed_contract_conditions + - signed_contract_record + - hr_approval_id + + - key: identity_documents + order: 2 + task_type: DOCUMENT_REQUEST + workflow_id: WF-DOC-001 + title: 신분서류 보완 + description: 보유하지 않았거나 유효성을 확인하지 못한 신분서류만 근로자 보안 링크로 요청하고 HR이 제출물을 검토합니다. + activation: + mode: MISSING_ANY + field_keys: [passport_status, arc_status] + depends_on: [] + depends_on_if_present: [] + checklist_items: + - item_code: WORKER_DOCUMENT_REQUEST_APPROVED + label: 근로자 안내문과 요청 서류 검토 + required: true + - item_code: SECURE_LINK_DELIVERY_RECORDED + label: 보안 링크 전달 완료 기록 + required: true + - item_code: IDENTITY_DOCUMENTS_SUBMITTED + label: 근로자 여권·외국인등록증 제출 확인 + required: true + - item_code: OCR_RESULT_HR_REVIEWED + label: OCR 추출값과 원본을 HR이 대조 검토 + required: true + completion_evidence: + - approved_notice_id + - verified_document_id + - ocr_review_id + + - key: employment_period_extension + order: 3 + task_type: EMPLOYMENT_PERIOD_EXTENSION + workflow_id: WF-CON-001 + title: 취업활동기간 연장 준비 + description: 서명된 근로계약서와 공식 안내를 기준으로 고용허가 관련 연장 신청을 준비하고 HR이 처리 결과를 기록합니다. + activation: + mode: ALWAYS + depends_on: [recontract] + depends_on_if_present: [identity_documents] + checklist_items: + - item_code: SIGNED_CONTRACT_READY_FOR_EXTENSION + label: 서명된 표준근로계약서 준비 확인 + required: true + - item_code: EMPLOYMENT_EXTENSION_REQUIREMENTS_REVIEWED + label: 취업활동기간 연장 신청정보와 필요서류 확인 + required: true + - item_code: EMPLOYMENT_EXTENSION_MANUALLY_SUBMITTED + label: HR이 공식 채널에서 직접 제출 + required: true + - item_code: EMPLOYMENT_EXTENSION_RESULT_RECORDED + label: 접수증 또는 처리결과 기록 + required: true + completion_evidence: + - signed_contract_record + - employment_permit_extension_receipt_or_note + - hr_approval_id + + - key: stay_period_extension + order: 4 + task_type: STAY_PERIOD_EXTENSION + workflow_id: WF-STY-001 + title: 체류기간 연장 준비와 결과 추적 + description: 앞선 재계약·취업활동기간 연장 결과와 신분서류를 바탕으로 통합신청서 초안을 검토하고 HR이 제출 결과를 기록합니다. + activation: + mode: ALWAYS + depends_on: [employment_period_extension] + depends_on_if_present: [identity_documents] + checklist_items: + - item_code: PASSPORT_AND_ARC_CURRENT_VERIFIED + label: 여권·외국인등록증 보유 및 유효 상태 확인 + required: true + - item_code: EMPLOYMENT_EXTENSION_RESULT_AVAILABLE + label: 취업활동기간 연장 처리결과 확인 + required: true + - item_code: INTEGRATED_APPLICATION_DRAFT_REVIEWED + label: 통합신청서 초안과 체류 관련 증빙 검토 + required: true + - item_code: STAY_EXTENSION_MANUALLY_SUBMITTED + label: HR이 하이코리아 또는 관할 기관에서 직접 제출 + required: true + - item_code: STAY_EXTENSION_RESULT_AND_NEXT_REVIEW_RECORDED + label: 처리결과와 다음 확인일 기록 + required: true + completion_evidence: + - stay_extension_receipt_or_note + - next_review_at + - hr_approval_id diff --git a/fowoco-knowledge/schemas/workflow-catalog.schema.json b/fowoco-knowledge/schemas/workflow-catalog.schema.json index 117fdd3..5f79700 100644 --- a/fowoco-knowledge/schemas/workflow-catalog.schema.json +++ b/fowoco-knowledge/schemas/workflow-catalog.schema.json @@ -3,7 +3,7 @@ "$id": "https://fowoco.local/schemas/workflow-catalog.schema.json", "title": "FOWOCO Workflow Catalog", "type": "object", - "required": ["version", "policy", "workflows"], + "required": ["version", "policy", "workflows", "case_templates"], "properties": { "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" }, "policy": { "type": "object" }, @@ -74,6 +74,105 @@ }, "additionalProperties": false } + }, + "case_templates": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["id", "name", "intent", "workflow_ids", "tasks"], + "properties": { + "id": { "type": "string", "pattern": "^CASE-[A-Z0-9-]+-[0-9]{3}$" }, + "name": { "type": "string", "minLength": 2 }, + "intent": { "type": "string" }, + "workflow_ids": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "pattern": "^WF-[A-Z]{3}(?:-[A-Z]{3})?-[0-9]{3}$" }, + "uniqueItems": true + }, + "tasks": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "key", + "order", + "task_type", + "workflow_id", + "title", + "description", + "activation", + "depends_on", + "depends_on_if_present", + "checklist_items", + "completion_evidence" + ], + "properties": { + "key": { "type": "string", "pattern": "^[a-z][a-z0-9_]+$" }, + "order": { "type": "integer", "minimum": 1 }, + "task_type": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]+$" }, + "workflow_id": { "type": "string", "pattern": "^WF-[A-Z]{3}(?:-[A-Z]{3})?-[0-9]{3}$" }, + "title": { "type": "string", "minLength": 2 }, + "description": { "type": "string", "minLength": 5 }, + "activation": { + "type": "object", + "required": ["mode"], + "properties": { + "mode": { "enum": ["ALWAYS", "MISSING_ANY"] }, + "field_keys": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "pattern": "^[a-z][a-z0-9_]+$" }, + "uniqueItems": true + } + }, + "allOf": [ + { + "if": { "properties": { "mode": { "const": "MISSING_ANY" } } }, + "then": { "required": ["field_keys"] } + } + ], + "additionalProperties": false + }, + "depends_on": { + "type": "array", + "items": { "type": "string", "pattern": "^[a-z][a-z0-9_]+$" }, + "uniqueItems": true + }, + "depends_on_if_present": { + "type": "array", + "items": { "type": "string", "pattern": "^[a-z][a-z0-9_]+$" }, + "uniqueItems": true + }, + "checklist_items": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["item_code", "label", "required"], + "properties": { + "item_code": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]+$" }, + "label": { "type": "string", "minLength": 2 }, + "required": { "type": "boolean" } + }, + "additionalProperties": false + } + }, + "completion_evidence": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "pattern": "^[a-z][a-z0-9_]+$" }, + "uniqueItems": true + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } } }, "additionalProperties": false diff --git a/fowoco-knowledge/src/fowoco_knowledge/repository.py b/fowoco-knowledge/src/fowoco_knowledge/repository.py index fdc528c..6be2f84 100644 --- a/fowoco-knowledge/src/fowoco_knowledge/repository.py +++ b/fowoco-knowledge/src/fowoco_knowledge/repository.py @@ -84,6 +84,15 @@ def load_context_files(self) -> dict[str, dict[str, Any]]: def list_workflows(self) -> list[dict[str, Any]]: return self.load_yaml("knowledge/workflow_catalog.yaml")["workflows"] + def list_case_templates(self) -> list[dict[str, Any]]: + return self.load_yaml("knowledge/workflow_catalog.yaml")["case_templates"] + + def get_case_template(self, case_template_id: str) -> dict[str, Any]: + for template in self.list_case_templates(): + if template["id"] == case_template_id: + return template + raise KeyError(f"Unknown case_template_id: {case_template_id}") + def get_workflow(self, workflow_id: str) -> dict[str, Any]: for workflow in self.list_workflows(): if workflow["id"] == workflow_id: diff --git a/fowoco-knowledge/src/fowoco_knowledge/validation.py b/fowoco-knowledge/src/fowoco_knowledge/validation.py index e6bd7d4..ceb22af 100644 --- a/fowoco-knowledge/src/fowoco_knowledge/validation.py +++ b/fowoco-knowledge/src/fowoco_knowledge/validation.py @@ -241,6 +241,9 @@ def _validate_cross_references(self) -> None: domains = self._index_unique(context["domains"]["domains"], "domain") sources = self._index_unique(context["sources"]["sources"], "source") workflows = self._index_unique(context["workflows"]["workflows"], "workflow") + case_templates = self._index_unique( + context["workflows"]["case_templates"], "case template" + ) checklists = self._index_unique(context["checklists"]["checklists"], "checklist") procedures = self._index_unique(context["procedures"]["procedures"], "procedure") slot_refs = context["slots"]["workflow_requirements"] @@ -262,6 +265,42 @@ def _validate_cross_references(self) -> None: if checklist_id and checklist_id not in checklists: self.errors.append(f"{workflow_id}: unknown checklist {checklist_id}") + for template_id, template in case_templates.items(): + if template["intent"] not in intents: + self.errors.append(f"{template_id}: unknown intent {template['intent']}") + for workflow_id in template["workflow_ids"]: + if workflow_id not in workflows: + self.errors.append(f"{template_id}: unknown workflow {workflow_id}") + task_keys = {task["key"] for task in template["tasks"]} + tasks_by_key = {task["key"]: task for task in template["tasks"]} + if len(task_keys) != len(template["tasks"]): + self.errors.append(f"{template_id}: duplicate task key") + task_orders = {task["order"] for task in template["tasks"]} + if len(task_orders) != len(template["tasks"]): + self.errors.append(f"{template_id}: duplicate task order") + for task in template["tasks"]: + if task["workflow_id"] not in template["workflow_ids"]: + self.errors.append( + f"{template_id}.{task['key']}: workflow not declared by template" + ) + dependencies = task["depends_on"] + task["depends_on_if_present"] + for dependency in dependencies: + if dependency not in task_keys: + self.errors.append( + f"{template_id}.{task['key']}: unknown dependency {dependency}" + ) + if dependency == task["key"]: + self.errors.append( + f"{template_id}.{task['key']}: task cannot depend on itself" + ) + elif dependency in tasks_by_key and ( + tasks_by_key[dependency]["order"] >= task["order"] + ): + self.errors.append( + f"{template_id}.{task['key']}: dependency {dependency} " + "must have a lower order" + ) + document_types = set(context["checklists"]["document_types"]) for checklist_id, checklist in checklists.items(): if checklist["workflow_id"] not in workflows: diff --git a/fowoco-knowledge/tests/test_repository.py b/fowoco-knowledge/tests/test_repository.py index b1c041e..6f9de35 100644 --- a/fowoco-knowledge/tests/test_repository.py +++ b/fowoco-knowledge/tests/test_repository.py @@ -2,6 +2,8 @@ from pathlib import Path +import yaml + from fowoco_knowledge.repository import KnowledgeRepository ROOT = Path(__file__).resolve().parents[1] @@ -55,3 +57,40 @@ def test_employment_change_context_uses_one_stop_reporting_procedure() -> None: assert procedure["submission_pattern"] == "one_stop_report" assert procedure["deadline_rule"]["value"] == 15 assert "SRC-LAW-IMMIGRATION-DECREE-24" in context["workflow"]["source_ids"] + + +def test_expiry_renewal_case_template_keeps_full_business_order() -> None: + template = KnowledgeRepository(ROOT).get_case_template("CASE-EXPIRY-RENEWAL-001") + + assert template["workflow_ids"] == ["WF-CON-001", "WF-DOC-001", "WF-STY-001"] + assert [task["key"] for task in template["tasks"]] == [ + "recontract", + "identity_documents", + "employment_period_extension", + "stay_period_extension", + ] + assert template["tasks"][1]["activation"] == { + "mode": "MISSING_ANY", + "field_keys": ["passport_status", "arc_status"], + } + assert template["tasks"][2]["depends_on"] == ["recontract"] + assert template["tasks"][3]["depends_on"] == ["employment_period_extension"] + assert len(template["tasks"][0]["checklist_items"]) == 6 + + +def test_expiry_renewal_demo_pack_matches_case_template() -> None: + repository = KnowledgeRepository(ROOT) + template = repository.get_case_template("CASE-EXPIRY-RENEWAL-001") + demo = yaml.safe_load( + (ROOT / "data/demo/expiry_renewal_golden.yaml").read_text(encoding="utf-8") + ) + + assert demo["contains_real_personal_data"] is False + assert demo["case_template_id"] == template["id"] + assert demo["workflow_ids"] == template["workflow_ids"] + assert [task["task_type"] for task in demo["expected_case"]["tasks"]] == [ + task["task_type"] for task in template["tasks"] + ] + assert all( + value is False for value in demo["guardrails"].values() + ) From bc4cbd3d1146f7ae06b71ad939e0ca5f1839d7a9 Mon Sep 17 00:00:00 2001 From: hywznn Date: Tue, 18 Aug 2026 11:42:59 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix(knowledge):=20=EC=84=9C=EB=A5=98=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=8A=B9=EC=9D=B8=20=EC=A0=84=ED=9B=84=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fowoco-knowledge/knowledge/workflow_catalog.yaml | 6 +++--- fowoco-knowledge/tests/test_repository.py | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/fowoco-knowledge/knowledge/workflow_catalog.yaml b/fowoco-knowledge/knowledge/workflow_catalog.yaml index 1aa08e3..828e939 100644 --- a/fowoco-knowledge/knowledge/workflow_catalog.yaml +++ b/fowoco-knowledge/knowledge/workflow_catalog.yaml @@ -444,13 +444,13 @@ case_templates: required: true - item_code: SECURE_LINK_DELIVERY_RECORDED label: 보안 링크 전달 완료 기록 - required: true + required: false - item_code: IDENTITY_DOCUMENTS_SUBMITTED label: 근로자 여권·외국인등록증 제출 확인 - required: true + required: false - item_code: OCR_RESULT_HR_REVIEWED label: OCR 추출값과 원본을 HR이 대조 검토 - required: true + required: false completion_evidence: - approved_notice_id - verified_document_id diff --git a/fowoco-knowledge/tests/test_repository.py b/fowoco-knowledge/tests/test_repository.py index 6f9de35..06f2331 100644 --- a/fowoco-knowledge/tests/test_repository.py +++ b/fowoco-knowledge/tests/test_repository.py @@ -76,6 +76,15 @@ def test_expiry_renewal_case_template_keeps_full_business_order() -> None: assert template["tasks"][2]["depends_on"] == ["recontract"] assert template["tasks"][3]["depends_on"] == ["employment_period_extension"] assert len(template["tasks"][0]["checklist_items"]) == 6 + identity_checklists = template["tasks"][1]["checklist_items"] + assert [item["item_code"] for item in identity_checklists if item["required"]] == [ + "WORKER_DOCUMENT_REQUEST_APPROVED" + ] + assert [item["item_code"] for item in identity_checklists if not item["required"]] == [ + "SECURE_LINK_DELIVERY_RECORDED", + "IDENTITY_DOCUMENTS_SUBMITTED", + "OCR_RESULT_HR_REVIEWED", + ] def test_expiry_renewal_demo_pack_matches_case_template() -> None: From b386c734908b184c9e980045f8d8451a623e1a39 Mon Sep 17 00:00:00 2001 From: hywznn Date: Tue, 18 Aug 2026 12:33:01 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix(knowledge):=20=EC=97=B0=EC=9E=A5=20?= =?UTF-8?q?=EC=97=85=EB=AC=B4=20=EC=8A=B9=EC=9D=B8=20=EC=A0=84=ED=9B=84=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fowoco-knowledge/knowledge/workflow_catalog.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fowoco-knowledge/knowledge/workflow_catalog.yaml b/fowoco-knowledge/knowledge/workflow_catalog.yaml index 828e939..a9ed4d5 100644 --- a/fowoco-knowledge/knowledge/workflow_catalog.yaml +++ b/fowoco-knowledge/knowledge/workflow_catalog.yaml @@ -475,10 +475,10 @@ case_templates: required: true - item_code: EMPLOYMENT_EXTENSION_MANUALLY_SUBMITTED label: HR이 공식 채널에서 직접 제출 - required: true + required: false - item_code: EMPLOYMENT_EXTENSION_RESULT_RECORDED label: 접수증 또는 처리결과 기록 - required: true + required: false completion_evidence: - signed_contract_record - employment_permit_extension_receipt_or_note @@ -506,10 +506,10 @@ case_templates: required: true - item_code: STAY_EXTENSION_MANUALLY_SUBMITTED label: HR이 하이코리아 또는 관할 기관에서 직접 제출 - required: true + required: false - item_code: STAY_EXTENSION_RESULT_AND_NEXT_REVIEW_RECORDED label: 처리결과와 다음 확인일 기록 - required: true + required: false completion_evidence: - stay_extension_receipt_or_note - next_review_at From 5ca49793d22356163192f424d841adacb7eff2b1 Mon Sep 17 00:00:00 2001 From: hywznn Date: Tue, 18 Aug 2026 12:38:08 +0900 Subject: [PATCH 4/4] =?UTF-8?q?style(knowledge):=20CI=20=ED=8F=AC=EB=A7=B7?= =?UTF-8?q?=20=EA=B7=9C=EC=B9=99=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fowoco-knowledge/src/fowoco_knowledge/validation.py | 4 +--- fowoco-knowledge/tests/test_repository.py | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fowoco-knowledge/src/fowoco_knowledge/validation.py b/fowoco-knowledge/src/fowoco_knowledge/validation.py index ceb22af..3beee62 100644 --- a/fowoco-knowledge/src/fowoco_knowledge/validation.py +++ b/fowoco-knowledge/src/fowoco_knowledge/validation.py @@ -241,9 +241,7 @@ def _validate_cross_references(self) -> None: domains = self._index_unique(context["domains"]["domains"], "domain") sources = self._index_unique(context["sources"]["sources"], "source") workflows = self._index_unique(context["workflows"]["workflows"], "workflow") - case_templates = self._index_unique( - context["workflows"]["case_templates"], "case template" - ) + case_templates = self._index_unique(context["workflows"]["case_templates"], "case template") checklists = self._index_unique(context["checklists"]["checklists"], "checklist") procedures = self._index_unique(context["procedures"]["procedures"], "procedure") slot_refs = context["slots"]["workflow_requirements"] diff --git a/fowoco-knowledge/tests/test_repository.py b/fowoco-knowledge/tests/test_repository.py index 06f2331..ae92477 100644 --- a/fowoco-knowledge/tests/test_repository.py +++ b/fowoco-knowledge/tests/test_repository.py @@ -100,6 +100,4 @@ def test_expiry_renewal_demo_pack_matches_case_template() -> None: assert [task["task_type"] for task in demo["expected_case"]["tasks"]] == [ task["task_type"] for task in template["tasks"] ] - assert all( - value is False for value in demo["guardrails"].values() - ) + assert all(value is False for value in demo["guardrails"].values())