{ "schemaVersion": "1.0", "contractVersion": "1.2.0", "sourceSha256": "24db1820d6c30f0db0daa8cead3a7f85c5285979dd054c98eed85d8d0470d626", "fixtureVersion": "1.2.0", "fixtureSourceSha256": "fad36546d0e548ed52840dd08c598f6003f6cdf1e6494678a3ac31ab03b0fbfd", "fixedReferenceClock": "2026-08-08T09:00:00Z", "scenarios": [ { "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.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" ], "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.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.create", "oms.order.read" ], "apiOperations": [ "oms.orders.register" ], "isolation": "database-reset", "assertionCount": 4, "evidence": [ "api-transcript", "db-assertions", "problem-json" ] }, { "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" ] }, { "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.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.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" ], "apiOperations": [], "isolation": "ui-only", "assertionCount": 4, "evidence": [ "playwright-trace", "screenshot" ] }, { "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.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.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.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" ] } ] }