{ "schemaVersion": "1.0", "contractVersion": "1.9.0", "sourceSha256": "c2a8910c136f08c0c33c3f7f5e78302a0723a35ab8506c3dbdee53634e2c5df3", "fixtureVersion": "1.4.0", "fixtureSourceSha256": "befb917413e52c04f3d0116f29aa2f07d3273d6b71d980a4f4416d48a5b3a162", "fixedReferenceClock": "2026-08-08T09:00:00Z", "scenarios": [ { "id": "scenario.common.design-system.interactions", "title": "KBX 컴포넌트 상태·키보드 상호작용 계약", "screenId": "COMMON-DS-001", "kind": "e2e", "tags": [ "component-contract", "accessibility", "keyboard", "visual-regression" ], "fixtureSets": [], "requiredPermissions": [], "apiOperations": [], "isolation": "ui-only", "assertionCount": 4, "evidence": [ "playwright-trace", "screenshot" ] }, { "id": "scenario.common.operations.stale-event", "title": "업무 예외 해결 후 오래된 Event가 재오픈하지 않음", "screenId": "COMMON-OPS-001", "kind": "integration", "tags": [ "exception", "outbox", "projection", "ordering" ], "fixtureSets": [ "fixture.common.operations" ], "requiredPermissions": [ "common.operations.read", "common.operations.resolve" ], "apiOperations": [ "common.operations.search" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "db-assertions", "projection-event-log" ] }, { "id": "scenario.common.reconcile.grace-period", "title": "OMS-WMS 대사 Grace Period 내 Pending 이후 Mismatch", "screenId": "COMMON-REC-001", "kind": "integration", "tags": [ "reconcile", "eventual-consistency" ], "fixtureSets": [ "fixture.common.reconcile" ], "requiredPermissions": [ "common.reconcile.read" ], "apiOperations": [ "common.reconcile.search" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "db-assertions", "clock-snapshot" ] }, { "id": "scenario.erp.inventory-move.workflow", "title": "ERP 재고이동 정상 상태전이와 잘못된 창고 차단", "screenId": "ERP-INV-MOVE-001", "kind": "integration", "tags": [ "workflow", "domain-validation", "audit" ], "fixtureSets": [ "fixture.erp.inventory-move" ], "requiredPermissions": [ "erp.inventory.move.read", "erp.inventory.move.write" ], "apiOperations": [], "isolation": "database-reset", "assertionCount": 3, "evidence": [ "db-assertions", "workflow-log" ] }, { "id": "scenario.erp.inventory.master-detail-context", "title": "ERP 재고 T05 Master/Detail Context·이력·Drill-down", "screenId": "ERP-INV-001", "kind": "e2e", "tags": [ "golden-screen", "master-detail", "context-retention", "drill-down", "history" ], "fixtureSets": [ "fixture.erp.inventory-explorer" ], "requiredPermissions": [ "erp.inventory.read" ], "apiOperations": [ "erp.inventory.search", "erp.inventory.locations", "erp.inventory.history" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "playwright-trace", "screenshot", "api-transcript" ] }, { "id": "scenario.erp.item-price.fast-entry", "title": "ERP 품목 단가 T04 Fast Entry 일괄저장", "screenId": "ERP-PRICE-001", "kind": "e2e", "tags": [ "golden-screen", "fast-entry", "lookup", "paste", "fill-down", "idempotency", "audit", "outbox" ], "fixtureSets": [ "fixture.erp.item-price-fast-entry" ], "requiredPermissions": [ "erp.item.price.read", "erp.item.price.write", "erp.item.read" ], "apiOperations": [ "lookup.items.resolveByCode", "erp.itemPrices.bulkSave" ], "isolation": "database-reset", "assertionCount": 6, "evidence": [ "playwright-trace", "api-transcript", "db-assertions", "problem-json" ] }, { "id": "scenario.external-data.kis.strict-expiry", "title": "KIS 현재가 만료 캐시를 최신값으로 사용하지 않음", "screenId": "COMMON-DATA-001", "kind": "integration", "tags": [ "external-data", "kis", "freshness", "strict" ], "fixtureSets": [ "fixture.external-data.kis" ], "requiredPermissions": [ "common.external-data.read" ], "apiOperations": [ "common.externalData.status" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "api-transcript", "db-assertions", "external-data-provenance" ] }, { "id": "scenario.external-data.opendart.stale-revalidate", "title": "OPENDART Stale 데이터 명시 표시 후 재수집 예약", "screenId": "COMMON-DATA-001", "kind": "integration", "tags": [ "external-data", "opendart", "stale-while-revalidate", "provenance" ], "fixtureSets": [ "fixture.external-data.opendart" ], "requiredPermissions": [ "common.external-data.read", "common.external-data.refresh" ], "apiOperations": [ "common.externalData.status", "common.externalData.refresh" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "api-transcript", "db-assertions", "external-data-provenance" ] }, { "id": "scenario.integration.inbox.duplicate", "title": "Inbox 동일 메시지 중복수신 1회 처리", "screenId": "COMMON-OPS-001", "kind": "integration", "tags": [ "integration", "inbox", "idempotency", "duplicate" ], "fixtureSets": [ "fixture.integration.inbox" ], "requiredPermissions": [ "common.operations.read" ], "apiOperations": [], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "db-assertions", "integration-receipt-log", "correlation-ids" ] }, { "id": "scenario.integration.manual-retry.idempotent", "title": "최종 실패 외부연계 수동 재처리 중복 클릭 방지", "screenId": "COMMON-OPS-001", "kind": "integration", "tags": [ "integration", "manual-retry", "idempotency" ], "fixtureSets": [ "fixture.integration.outbox" ], "requiredPermissions": [ "common.integration.read", "common.integration.retry" ], "apiOperations": [ "common.integrations.retryAttempt" ], "isolation": "database-reset", "assertionCount": 3, "evidence": [ "api-transcript", "db-assertions", "correlation-ids" ] }, { "id": "scenario.integration.outbox.permanent-failure", "title": "외부연계 영구 실패가 업무 예외로 승격", "screenId": "COMMON-OPS-001", "kind": "integration", "tags": [ "integration", "outbox", "permanent-failure", "exception" ], "fixtureSets": [ "fixture.integration.outbox" ], "requiredPermissions": [ "common.operations.read" ], "apiOperations": [], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "db-assertions", "integration-attempt-log", "correlation-ids" ] }, { "id": "scenario.integration.outbox.transient-retry", "title": "Outbox 외부연계 일시 장애 후 자동 재시도", "screenId": "COMMON-OPS-001", "kind": "integration", "tags": [ "integration", "outbox", "retry", "polly", "hangfire" ], "fixtureSets": [ "fixture.integration.outbox" ], "requiredPermissions": [ "common.operations.read" ], "apiOperations": [], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "api-transcript", "db-assertions", "integration-attempt-log", "correlation-ids" ] }, { "id": "scenario.oms.order-import.partial", "title": "OMS 주문 Excel 검증 후 부분 반영", "screenId": "OMS-ORD-003", "kind": "e2e", "tags": [ "excel", "mapping", "staging", "partial-success", "job" ], "fixtureSets": [ "fixture.oms.order-import" ], "requiredPermissions": [ "oms.order.import" ], "apiOperations": [ "common.imports.createSession", "common.imports.validate", "common.imports.commit", "common.imports.getSession" ], "isolation": "database-reset", "assertionCount": 7, "evidence": [ "playwright-trace", "api-transcript", "import-session-snapshot", "error-workbook-metadata", "db-assertions", "problem-json" ] }, { "id": "scenario.oms.order-list.all-filtered-ship", "title": "OMS 주문조회 검색결과 전체선택 안전 출고 계약", "screenId": "OMS-ORD-001", "kind": "contract", "tags": [ "golden-screen", "bulk", "all-filtered", "filter-snapshot", "idempotency" ], "fixtureSets": [ "fixture.oms.orders.bulk-ship" ], "requiredPermissions": [ "oms.order.read", "oms.order.ship" ], "apiOperations": [ "oms.orders.search", "oms.orders.ship" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "vitest-contract", "api-transcript", "db-assertions", "correlation-ids" ] }, { "id": "scenario.oms.order-list.bulk-ship", "title": "OMS 주문조회 대량 출고지시 부분성공", "screenId": "OMS-ORD-001", "kind": "e2e", "tags": [ "golden-screen", "bulk", "idempotency", "audit", "outbox" ], "fixtureSets": [ "fixture.oms.orders.bulk-ship" ], "requiredPermissions": [ "oms.order.read", "oms.order.ship" ], "apiOperations": [ "oms.orders.search", "oms.orders.ship" ], "isolation": "database-reset", "assertionCount": 7, "evidence": [ "playwright-trace", "screenshot", "api-transcript", "db-assertions", "correlation-ids" ] }, { "id": "scenario.oms.order-register.conflict", "title": "OMS 주문수정 Optimistic Concurrency 충돌", "screenId": "OMS-ORD-002", "kind": "integration", "tags": [ "concurrency", "conflict", "recovery" ], "fixtureSets": [ "fixture.oms.order-conflict" ], "requiredPermissions": [ "oms.order.read", "erp.item.read", "oms.order.write" ], "apiOperations": [ "oms.orders.update", "oms.orders.get" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "api-transcript", "db-assertions", "problem-json" ] }, { "id": "scenario.oms.order-register.fast-entry", "title": "OMS 주문등록 Fast Entry Grid 대량입력 계약", "screenId": "OMS-ORD-002", "kind": "contract", "tags": [ "golden-screen", "fast-entry", "paste", "fill-down", "inline-validation" ], "fixtureSets": [ "fixture.oms.order-register" ], "requiredPermissions": [ "oms.order.create", "oms.order.read" ], "apiOperations": [], "isolation": "ui-only", "assertionCount": 5, "evidence": [ "vitest-contract", "playwright-trace", "component-catalog" ] }, { "id": "scenario.oms.order-register.keyboard", "title": "OMS 주문등록 키보드 중심 저장", "screenId": "OMS-ORD-002", "kind": "e2e", "tags": [ "golden-screen", "keyboard", "lookup", "validation", "audit" ], "fixtureSets": [ "fixture.oms.order-register" ], "requiredPermissions": [ "oms.order.create", "oms.order.read", "erp.item.read" ], "apiOperations": [ "lookup.customers.search", "lookup.items.resolveByCode", "lookup.warehouses.resolveByCode", "oms.orders.register" ], "isolation": "database-reset", "assertionCount": 6, "evidence": [ "playwright-trace", "screenshot", "api-transcript", "db-assertions" ] }, { "id": "scenario.shell.unsaved-tab", "title": "Workspace Tab 미저장 변경 보호", "screenId": "OMS-ORD-002", "kind": "e2e", "tags": [ "shell", "dirty-state", "keyboard" ], "fixtureSets": [ "fixture.shell.user" ], "requiredPermissions": [ "oms.order.create", "oms.order.read", "erp.item.read" ], "apiOperations": [], "isolation": "ui-only", "assertionCount": 4, "evidence": [ "playwright-trace", "screenshot" ] }, { "id": "scenario.wms.picking.idempotent-replay", "title": "WMS 피킹 응답유실 후 동일 Scan Replay", "screenId": "WMS-PICK-001", "kind": "e2e", "tags": [ "golden-screen", "scanner", "idempotency", "network" ], "fixtureSets": [ "fixture.wms.picking" ], "requiredPermissions": [ "wms.picking.execute" ], "apiOperations": [ "wms.picking.getTask", "wms.picking.start", "wms.picking.scan" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "playwright-trace", "api-transcript", "db-assertions", "scanner-event-log" ] }, { "id": "scenario.wms.picking.wrong-item", "title": "WMS 다른 상품 Scan은 재시도 Queue 비대상", "screenId": "WMS-PICK-001", "kind": "e2e", "tags": [ "scanner", "business-error", "retry-policy" ], "fixtureSets": [ "fixture.wms.picking" ], "requiredPermissions": [ "wms.picking.execute" ], "apiOperations": [ "wms.picking.scan" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "playwright-trace", "api-transcript", "db-assertions" ] }, { "id": "scenario.erp.item-master.lifecycle", "title": "ERP 품목관리 CRUD·Concurrency·Audit Lifecycle", "screenId": "ERP-MST-ITEM-001", "kind": "integration", "tags": [ "golden-screen", "master-crud", "concurrency", "audit", "state-policy" ], "fixtureSets": [ "fixture.erp.item-master-lifecycle" ], "requiredPermissions": [ "erp.item.read", "erp.item.write" ], "apiOperations": [ "erp.items.get", "erp.items.update", "erp.items.audit", "erp.items.deactivate" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "api-transcript", "db-assertions", "problem-json", "screenshot" ] }, { "id": "scenario.oms.order-register.lifecycle", "title": "OMS 주문 작성→확정·읽기전용·Audit Lifecycle", "screenId": "OMS-ORD-002", "kind": "e2e", "tags": [ "golden-screen", "transaction", "workflow", "audit", "state-policy" ], "fixtureSets": [ "fixture.oms.order-conflict" ], "requiredPermissions": [ "oms.order.create", "oms.order.read", "oms.order.confirm", "erp.item.read" ], "apiOperations": [ "oms.orders.get", "oms.orders.confirm", "oms.orders.audit" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "playwright-trace", "api-transcript", "db-assertions", "screenshot" ] }, { "id": "scenario.shell.home-navigation-security", "title": "Home Workbench·권한필터·Scope/Route/Workspace 격리", "screenId": "OMS-ORD-001", "kind": "e2e", "tags": [ "shell", "home", "navigation", "security", "preference", "workspace" ], "fixtureSets": [], "requiredPermissions": [ "oms.order.read" ], "apiOperations": [], "isolation": "ui-only", "assertionCount": 11, "evidence": [ "playwright-trace", "screenshot", "local-storage-snapshot" ] }, { "id": "scenario.kbx.template-runtime-utility", "title": "T01~T09 Runtime State·Help/AI/제안 Utility 공통 계약", "screenId": "OMS-ORD-001", "kind": "e2e", "tags": [ "template-contract", "runtime-state", "utility", "accessibility", "recovery" ], "fixtureSets": [], "requiredPermissions": [ "oms.order.read", "common.ai.use", "common.suggestion.create" ], "apiOperations": [], "isolation": "ui-only", "assertionCount": 5, "evidence": [ "playwright-trace", "screenshot" ] }, { "id": "scenario.common.design-system.form-composition", "title": "Desktop Form 2-column·Full-span·Responsive 표준 계약", "screenId": "COMMON-DS-001", "kind": "e2e", "tags": [ "template-contract", "form", "responsive", "accessibility", "design-token" ], "fixtureSets": [], "requiredPermissions": [], "apiOperations": [], "isolation": "ui-only", "assertionCount": 5, "evidence": [ "playwright-trace", "screenshot" ] }, { "id": "scenario.shell.module-route-recovery", "title": "Global Module Selector·딥링크 복구·Navigation Capability 보안 계약", "screenId": "OMS-ORD-001", "kind": "e2e", "tags": [ "shell", "navigation", "security", "deep-link", "accessibility" ], "fixtureSets": [], "requiredPermissions": [ "oms.order.read" ], "apiOperations": [], "isolation": "ui-only", "assertionCount": 6, "evidence": [ "playwright-trace", "screenshot" ] }, { "id": "scenario.erp.item-master.keyboard-recovery", "title": "ERP 품목 T02 조회·권한·Dirty·Conflict 복구", "screenId": "ERP-MST-ITEM-001", "kind": "e2e", "tags": [ "golden-screen", "master-crud", "keyboard", "permission", "concurrency", "audit", "recovery" ], "fixtureSets": [ "fixture.erp.item-master-lifecycle" ], "requiredPermissions": [ "erp.item.read", "erp.item.write" ], "apiOperations": [ "erp.items.search", "erp.items.get" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "playwright-trace", "screenshot", "api-transcript", "db-assertions", "problem-json" ] }, { "id": "scenario.common.operations.queue-recovery", "title": "업무 예외 T06 Queue 조회·상세 Context·재시도 복구", "screenId": "COMMON-OPS-001", "kind": "e2e", "tags": [ "golden-screen", "queue", "exception", "recovery", "context-retention", "permission" ], "fixtureSets": [ "fixture.common.operations" ], "requiredPermissions": [ "common.operations.read", "common.operations.retry" ], "apiOperations": [ "common.operations.search", "common.operations.retry" ], "isolation": "database-reset", "assertionCount": 5, "evidence": [ "playwright-trace", "screenshot", "api-transcript", "db-assertions" ] }, { "id": "scenario.common.reconcile.mismatch-recovery", "title": "업무 대사 T07 불일치 필터·비교 Context·복구", "screenId": "COMMON-REC-001", "kind": "e2e", "tags": [ "golden-screen", "reconcile", "mismatch-filter", "eventual-consistency", "recovery", "context-retention" ], "fixtureSets": [ "fixture.common.reconcile" ], "requiredPermissions": [ "common.reconcile.read" ], "apiOperations": [ "common.reconcile.search" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "playwright-trace", "screenshot", "api-transcript", "db-assertions" ] } ] }