V13-FE-011: finalize search list layout slice
This commit is contained in:
@@ -0,0 +1,803 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"apiVersion": "2.1.0",
|
||||
"problemSchema": "../problems/kbx.problem.schema.json",
|
||||
"operations": [
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/common/ai/ask",
|
||||
"permission": "common.ai.use",
|
||||
"source": "backend/Modules/Common/Ai/Ask/Endpoint.cs",
|
||||
"id": "common.ai.ask",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/experiments/assignments",
|
||||
"permission": "common.experiment.evaluate",
|
||||
"source": "backend/Modules/Common/Experiments/Assignments/Endpoint.cs",
|
||||
"id": "common.experiments.assignments",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/experiments",
|
||||
"permission": "common.experiment.read",
|
||||
"source": "backend/Modules/Common/Experiments/Overview/Endpoint.cs",
|
||||
"id": "common.experiments.overview",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/kbx/experiments/{experimentId}/rollback",
|
||||
"permission": "common.experiment.manage",
|
||||
"source": "backend/Modules/Common/Experiments/Rollback/Endpoint.cs",
|
||||
"id": "common.experiments.rollback",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/kbx/experiments/{experimentId}/rollout",
|
||||
"permission": "common.experiment.manage",
|
||||
"source": "backend/Modules/Common/Experiments/Rollout/Endpoint.cs",
|
||||
"id": "common.experiments.rollout",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/kbx/external-data/{datasetId}/refresh",
|
||||
"permission": "common.external-data.refresh",
|
||||
"source": "backend/Modules/Common/ExternalData/Refresh/Endpoint.cs",
|
||||
"id": "common.externalData.refresh",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
202
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/external-data/status",
|
||||
"permission": "common.external-data.read",
|
||||
"source": "backend/Modules/Common/ExternalData/Status/Endpoint.cs",
|
||||
"id": "common.externalData.status",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/imports/sessions/{sessionId:guid}/commit",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/CommitEndpoint.cs",
|
||||
"id": "common.imports.commit",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/imports/sessions",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/CreateSessionEndpoint.cs",
|
||||
"id": "common.imports.createSession",
|
||||
"kind": "upload",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
],
|
||||
"contentType": "multipart/form-data"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/imports/sessions/{sessionId:guid}/errors.xlsx",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/ErrorWorkbookEndpoint.cs",
|
||||
"id": "common.imports.errorWorkbook",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
],
|
||||
"responseType": "blob"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/imports/sessions/{sessionId:guid}",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/GetSessionEndpoint.cs",
|
||||
"id": "common.imports.getSession",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/api/imports/sessions/{sessionId:guid}/mapping",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/SaveMappingEndpoint.cs",
|
||||
"id": "common.imports.saveMapping",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/imports/sessions/{sessionId:guid}/saved-mappings",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/SaveNamedMappingEndpoint.cs",
|
||||
"id": "common.imports.saveNamedMapping",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
204
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/imports/{importType}/template",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/TemplateEndpoint.cs",
|
||||
"id": "common.imports.template",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
],
|
||||
"responseType": "blob"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/imports/sessions/{sessionId:guid}/validate",
|
||||
"permission": "imports.execute",
|
||||
"source": "backend/Modules/Common/Imports/Endpoints/ValidateEndpoint.cs",
|
||||
"id": "common.imports.validate",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/integrations/attempts/{attemptId:guid}",
|
||||
"permission": "common.integration.read",
|
||||
"source": "backend/Modules/Common/Integrations/Attempts/Get/Endpoint.cs",
|
||||
"id": "common.integrations.getAttempt",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/integrations/attempts/{attemptId:guid}/retry",
|
||||
"permission": "common.integration.retry",
|
||||
"source": "backend/Modules/Common/Integrations/Attempts/Retry/Endpoint.cs",
|
||||
"id": "common.integrations.retryAttempt",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/operations/work-items/claim",
|
||||
"permission": "common.operations.claim",
|
||||
"source": "backend/Modules/Common/Operations/Claim/Endpoint.cs",
|
||||
"id": "common.operations.claim",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/operations/work-items/resolve",
|
||||
"permission": "common.operations.resolve",
|
||||
"source": "backend/Modules/Common/Operations/Resolve/Endpoint.cs",
|
||||
"id": "common.operations.resolve",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/operations/work-items/{id:guid}/retry",
|
||||
"permission": "common.operations.retry",
|
||||
"source": "backend/Modules/Common/Operations/Retry/Endpoint.cs",
|
||||
"id": "common.operations.retry",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/operations/work-items",
|
||||
"permission": "common.operations.read",
|
||||
"source": "backend/Modules/Common/Operations/Search/Endpoint.cs",
|
||||
"id": "common.operations.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/reconcile/items/create-exceptions",
|
||||
"permission": "common.operations.create",
|
||||
"source": "backend/Modules/Common/Reconcile/CreateExceptions/Endpoint.cs",
|
||||
"id": "common.reconcile.createExceptions",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/reconcile/items",
|
||||
"permission": "common.reconcile.read",
|
||||
"source": "backend/Modules/Common/Reconcile/Search/Endpoint.cs",
|
||||
"id": "common.reconcile.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/runtime/notice",
|
||||
"permission": "common.runtime.read",
|
||||
"source": "backend/Modules/Common/Runtime/Health/Endpoint.cs",
|
||||
"id": "common.runtime.notice",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/kbx/runtime/notifications/{Id}/read",
|
||||
"permission": "common.runtime.read",
|
||||
"source": "backend/Modules/Common/Runtime/Notifications/Endpoint.cs",
|
||||
"id": "common.runtime.notificationRead",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
204
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/runtime/notifications",
|
||||
"permission": "common.runtime.read",
|
||||
"source": "backend/Modules/Common/Runtime/Notifications/Endpoint.cs",
|
||||
"id": "common.runtime.notifications",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/runtime/operations",
|
||||
"permission": "common.runtime.read",
|
||||
"source": "backend/Modules/Common/Runtime/Operations/Endpoint.cs",
|
||||
"id": "common.runtime.operations",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/common/suggestions",
|
||||
"permission": "common.suggestion.create",
|
||||
"source": "backend/Modules/Common/Suggestions/Submit/Endpoint.cs",
|
||||
"id": "common.suggestions.submit",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/kbx/ux/events",
|
||||
"permission": "common.telemetry.write",
|
||||
"source": "backend/Modules/Common/UxTelemetry/Ingest/Endpoint.cs",
|
||||
"id": "common.uxTelemetry.ingest",
|
||||
"kind": "command",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
204
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/kbx/ux/metrics",
|
||||
"permission": "common.ux.read",
|
||||
"source": "backend/Modules/Common/UxTelemetry/Metrics/Endpoint.cs",
|
||||
"id": "common.uxTelemetry.metrics",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/erp/inventory/{itemId}/history",
|
||||
"permission": "erp.inventory.read",
|
||||
"source": "backend/Modules/ERP/Inventory/Search/HistoryEndpoint.cs",
|
||||
"id": "erp.inventory.history",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/erp/inventory/{itemId}/locations",
|
||||
"permission": "erp.inventory.read",
|
||||
"source": "backend/Modules/ERP/Inventory/Search/LocationsEndpoint.cs",
|
||||
"id": "erp.inventory.locations",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/erp/inventory",
|
||||
"permission": "erp.inventory.read",
|
||||
"source": "backend/Modules/ERP/Inventory/Search/Endpoint.cs",
|
||||
"id": "erp.inventory.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/erp/item-prices/bulk",
|
||||
"permission": "erp.item.price.write",
|
||||
"source": "backend/Modules/ERP/ItemPrices/BulkSave/Endpoint.cs",
|
||||
"id": "erp.itemPrices.bulkSave",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/erp/items/{id}",
|
||||
"permission": "erp.item.read",
|
||||
"source": "backend/Modules/ERP/Items/Get/Endpoint.cs",
|
||||
"id": "erp.items.get",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/erp/items",
|
||||
"permission": "erp.item.read",
|
||||
"source": "backend/Modules/ERP/Items/Search/Endpoint.cs",
|
||||
"id": "erp.items.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/customers/by-code/{code}",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Customers/ResolveByCodeEndpoint.cs",
|
||||
"id": "lookup.customers.resolveByCode",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/customers/{id}",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Customers/ResolveEndpoint.cs",
|
||||
"id": "lookup.customers.resolveById",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/customers",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Customers/Endpoint.cs",
|
||||
"id": "lookup.customers.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/items/by-code/{code}",
|
||||
"permission": "erp.item.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Items/ResolveByCodeEndpoint.cs",
|
||||
"id": "lookup.items.resolveByCode",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/items/{id}",
|
||||
"permission": "erp.item.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Items/ResolveEndpoint.cs",
|
||||
"id": "lookup.items.resolveById",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/items",
|
||||
"permission": "erp.item.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Items/Endpoint.cs",
|
||||
"id": "lookup.items.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/warehouses/by-code/{code}",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Warehouses/ResolveByCodeEndpoint.cs",
|
||||
"id": "lookup.warehouses.resolveByCode",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/warehouses/{id}",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Warehouses/ResolveEndpoint.cs",
|
||||
"id": "lookup.warehouses.resolveById",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/lookups/warehouses",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Lookups/Warehouses/Endpoint.cs",
|
||||
"id": "lookup.warehouses.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/claims/{id:guid}/approve",
|
||||
"permission": "oms.claim.approve",
|
||||
"source": "backend/Modules/OMS/Claims/Workflow/Endpoint.cs",
|
||||
"id": "oms.claims.approve",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/claims/{id:guid}/complete",
|
||||
"permission": "oms.claim.process",
|
||||
"source": "backend/Modules/OMS/Claims/Workflow/Endpoint.cs",
|
||||
"id": "oms.claims.complete",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/claims/{id:guid}/hold",
|
||||
"permission": "oms.claim.hold",
|
||||
"source": "backend/Modules/OMS/Claims/Workflow/Endpoint.cs",
|
||||
"id": "oms.claims.hold",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/oms/claims",
|
||||
"permission": "oms.claim.read",
|
||||
"source": "backend/Modules/OMS/Claims/Search/Endpoint.cs",
|
||||
"id": "oms.claims.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/claims/{id:guid}/start",
|
||||
"permission": "oms.claim.process",
|
||||
"source": "backend/Modules/OMS/Claims/Workflow/Endpoint.cs",
|
||||
"id": "oms.claims.start",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/orders/register",
|
||||
"permission": "oms.order.create",
|
||||
"source": "backend/Modules/OMS/Orders/Register/Endpoint.cs",
|
||||
"id": "oms.orders.register",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/oms/orders",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Orders/Search/Endpoint.cs",
|
||||
"id": "oms.orders.search",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/orders/ship",
|
||||
"permission": "oms.order.ship",
|
||||
"source": "backend/Modules/OMS/Orders/Ship/Endpoint.cs",
|
||||
"id": "oms.orders.ship",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/wms/picking/tasks/{taskId:guid}",
|
||||
"permission": "wms.picking.execute",
|
||||
"source": "backend/Modules/WMS/Picking/GetTask/Endpoint.cs",
|
||||
"id": "wms.picking.getTask",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/wms/picking/tasks/{taskId:guid}/exceptions",
|
||||
"permission": "wms.picking.execute",
|
||||
"source": "backend/Modules/WMS/Picking/Exceptions/Endpoint.cs",
|
||||
"id": "wms.picking.reportException",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/wms/picking/tasks/{taskId:guid}/scan",
|
||||
"permission": "wms.picking.execute",
|
||||
"source": "backend/Modules/WMS/Picking/Scan/Endpoint.cs",
|
||||
"id": "wms.picking.scan",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200,
|
||||
422
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/wms/picking/tasks/{taskId:guid}/quantity",
|
||||
"permission": "wms.picking.execute",
|
||||
"source": "backend/Modules/WMS/Picking/SetQuantity/Endpoint.cs",
|
||||
"id": "wms.picking.setQuantity",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/wms/picking/tasks/{taskId:guid}/start",
|
||||
"permission": "wms.picking.execute",
|
||||
"source": "backend/Modules/WMS/Picking/Start/Endpoint.cs",
|
||||
"id": "wms.picking.start",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/erp/items",
|
||||
"permission": "erp.item.create",
|
||||
"source": "backend/Modules/ERP/Items/Save/CreateEndpoint.cs",
|
||||
"id": "erp.items.create",
|
||||
"kind": "command",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/api/erp/items/{id}",
|
||||
"permission": "erp.item.write",
|
||||
"source": "backend/Modules/ERP/Items/Save/UpdateEndpoint.cs",
|
||||
"id": "erp.items.update",
|
||||
"kind": "command",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/erp/items/{id}/deactivate",
|
||||
"permission": "erp.item.write",
|
||||
"source": "backend/Modules/ERP/Items/Deactivate/Endpoint.cs",
|
||||
"id": "erp.items.deactivate",
|
||||
"kind": "command",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/erp/items/{id}/audit",
|
||||
"permission": "erp.item.read",
|
||||
"source": "backend/Modules/ERP/Items/Audit/Endpoint.cs",
|
||||
"id": "erp.items.audit",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/oms/orders/{id}",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Orders/Get/Endpoint.cs",
|
||||
"id": "oms.orders.get",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/oms/orders/{id}/confirm",
|
||||
"permission": "oms.order.confirm",
|
||||
"source": "backend/Modules/OMS/Orders/Confirm/Endpoint.cs",
|
||||
"id": "oms.orders.confirm",
|
||||
"kind": "command",
|
||||
"idempotency": "required",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/oms/orders/{id}/audit",
|
||||
"permission": "oms.order.read",
|
||||
"source": "backend/Modules/OMS/Orders/Audit/Endpoint.cs",
|
||||
"id": "oms.orders.audit",
|
||||
"kind": "query",
|
||||
"idempotency": "none",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/api/oms/orders/{id}",
|
||||
"permission": "oms.order.write",
|
||||
"source": "backend/Modules/OMS/Orders/Register/UpdateEndpoint.cs",
|
||||
"id": "oms.orders.update",
|
||||
"kind": "command",
|
||||
"idempotency": "supported",
|
||||
"successStatuses": [
|
||||
200
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,582 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"permissionVersion": "1.8.0",
|
||||
"principles": {
|
||||
"backendFinalEnforcement": true,
|
||||
"frontendPurpose": "ux-presentation",
|
||||
"roleMappingOwnedByDeployment": true,
|
||||
"aiEffectivePermission": "user-permission ∩ ai-allowed-action"
|
||||
},
|
||||
"permissions": [
|
||||
{
|
||||
"id": "common.ai.use",
|
||||
"module": "COMMON",
|
||||
"resource": "ai",
|
||||
"action": "use",
|
||||
"risk": "medium",
|
||||
"description": "AI 설명·추천·초안 기능 사용",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.ai.execute",
|
||||
"module": "COMMON",
|
||||
"resource": "ai",
|
||||
"action": "execute",
|
||||
"risk": "high",
|
||||
"description": "AI 승인 제안의 실제 Command 실행 허용",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.operations.claim",
|
||||
"module": "COMMON",
|
||||
"resource": "operations",
|
||||
"action": "claim",
|
||||
"risk": "medium",
|
||||
"description": "업무 예외를 내 처리건으로 지정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.operations.create",
|
||||
"module": "COMMON",
|
||||
"resource": "operations",
|
||||
"action": "create",
|
||||
"risk": "medium",
|
||||
"description": "대사 결과에서 운영 예외 생성",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.operations.read",
|
||||
"module": "COMMON",
|
||||
"resource": "operations",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "업무 예외 센터 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.operations.resolve",
|
||||
"module": "COMMON",
|
||||
"resource": "operations",
|
||||
"action": "resolve",
|
||||
"risk": "high",
|
||||
"description": "수동 해결이 허용된 운영 예외 해결",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.operations.retry",
|
||||
"module": "COMMON",
|
||||
"resource": "operations",
|
||||
"action": "retry",
|
||||
"risk": "high",
|
||||
"description": "등록된 안전한 예외 Action 재처리",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.reconcile.read",
|
||||
"module": "COMMON",
|
||||
"resource": "reconcile",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "업무 데이터 대사 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.runtime.read",
|
||||
"module": "COMMON",
|
||||
"resource": "runtime",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "런타임 상태·작업·알림 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.suggestion.create",
|
||||
"module": "COMMON",
|
||||
"resource": "suggestion",
|
||||
"action": "create",
|
||||
"risk": "low",
|
||||
"description": "현재 화면 사용자 제안 등록",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.inventory.move.confirm",
|
||||
"module": "ERP",
|
||||
"resource": "inventory-move",
|
||||
"action": "confirm",
|
||||
"risk": "high",
|
||||
"description": "재고이동 확정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.inventory.move.read",
|
||||
"module": "ERP",
|
||||
"resource": "inventory-move",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "재고이동 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.inventory.move.receive",
|
||||
"module": "ERP",
|
||||
"resource": "inventory-move",
|
||||
"action": "receive",
|
||||
"risk": "high",
|
||||
"description": "이동재고 입고완료",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.inventory.move.ship",
|
||||
"module": "ERP",
|
||||
"resource": "inventory-move",
|
||||
"action": "ship",
|
||||
"risk": "high",
|
||||
"description": "이동재고 출고",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.inventory.move.write",
|
||||
"module": "ERP",
|
||||
"resource": "inventory-move",
|
||||
"action": "write",
|
||||
"risk": "medium",
|
||||
"description": "재고이동 작성·수정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.inventory.read",
|
||||
"module": "ERP",
|
||||
"resource": "inventory",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "재고현황 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.item.price.read",
|
||||
"module": "ERP",
|
||||
"resource": "item-price",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "품목 단가 일괄등록 화면 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.item.price.write",
|
||||
"module": "ERP",
|
||||
"resource": "item-price",
|
||||
"action": "write",
|
||||
"risk": "medium",
|
||||
"description": "품목 단가 일괄등록·수정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.item.create",
|
||||
"module": "ERP",
|
||||
"resource": "item",
|
||||
"action": "create",
|
||||
"risk": "medium",
|
||||
"description": "품목 신규·복사",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.item.read",
|
||||
"module": "ERP",
|
||||
"resource": "item",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "품목 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.item.write",
|
||||
"module": "ERP",
|
||||
"resource": "item",
|
||||
"action": "write",
|
||||
"risk": "medium",
|
||||
"description": "품목 수정·사용중지",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.purchase.cancel",
|
||||
"module": "ERP",
|
||||
"resource": "purchase",
|
||||
"action": "cancel",
|
||||
"risk": "high",
|
||||
"description": "구매 취소",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.purchase.confirm",
|
||||
"module": "ERP",
|
||||
"resource": "purchase",
|
||||
"action": "confirm",
|
||||
"risk": "high",
|
||||
"description": "구매 확정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.purchase.read",
|
||||
"module": "ERP",
|
||||
"resource": "purchase",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "구매 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "erp.purchase.write",
|
||||
"module": "ERP",
|
||||
"resource": "purchase",
|
||||
"action": "write",
|
||||
"risk": "medium",
|
||||
"description": "구매 작성·수정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "imports.execute",
|
||||
"module": "COMMON",
|
||||
"resource": "imports",
|
||||
"action": "execute",
|
||||
"risk": "high",
|
||||
"description": "Excel Import 생성·검증·반영",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "kbx.design.read",
|
||||
"module": "COMMON",
|
||||
"resource": "design-system",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "KBX 내부 컴포넌트 카탈로그 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.claim.approve",
|
||||
"module": "OMS",
|
||||
"resource": "claim",
|
||||
"action": "approve",
|
||||
"risk": "high",
|
||||
"description": "클레임 승인",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.claim.hold",
|
||||
"module": "OMS",
|
||||
"resource": "claim",
|
||||
"action": "hold",
|
||||
"risk": "medium",
|
||||
"description": "클레임 보류",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.claim.process",
|
||||
"module": "OMS",
|
||||
"resource": "claim",
|
||||
"action": "process",
|
||||
"risk": "high",
|
||||
"description": "클레임 처리 시작·완료",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.claim.read",
|
||||
"module": "OMS",
|
||||
"resource": "claim",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "반품·클레임 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.create",
|
||||
"module": "OMS",
|
||||
"resource": "order",
|
||||
"action": "create",
|
||||
"risk": "medium",
|
||||
"description": "주문 신규 등록",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.import",
|
||||
"module": "OMS",
|
||||
"resource": "order",
|
||||
"action": "import",
|
||||
"risk": "high",
|
||||
"description": "주문 Excel Import 실행",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.read",
|
||||
"module": "OMS",
|
||||
"resource": "order",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "주문 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.ship",
|
||||
"module": "OMS",
|
||||
"resource": "order",
|
||||
"action": "ship",
|
||||
"risk": "high",
|
||||
"description": "주문 출고지시",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.recipient.unmask",
|
||||
"module": "OMS",
|
||||
"resource": "order-recipient",
|
||||
"action": "sensitive-read",
|
||||
"risk": "high",
|
||||
"description": "주문 수취인 개인정보 전체보기",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.recipient.export",
|
||||
"module": "OMS",
|
||||
"resource": "order-recipient",
|
||||
"action": "sensitive-export",
|
||||
"risk": "high",
|
||||
"description": "주문 수취인 개인정보 비마스킹 Export",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "wms.inventory.count",
|
||||
"module": "WMS",
|
||||
"resource": "inventory",
|
||||
"action": "count",
|
||||
"risk": "high",
|
||||
"description": "현장 재고실사 실행",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "wms.picking.execute",
|
||||
"module": "WMS",
|
||||
"resource": "picking",
|
||||
"action": "execute",
|
||||
"risk": "high",
|
||||
"description": "출고 피킹 작업 실행",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "wms.putaway.execute",
|
||||
"module": "WMS",
|
||||
"resource": "putaway",
|
||||
"action": "execute",
|
||||
"risk": "high",
|
||||
"description": "입고 적치 작업 실행",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "wms.receiving.execute",
|
||||
"module": "WMS",
|
||||
"resource": "receiving",
|
||||
"action": "execute",
|
||||
"risk": "high",
|
||||
"description": "입고 검수 작업 실행",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "wms.work.execute",
|
||||
"module": "WMS",
|
||||
"resource": "work",
|
||||
"action": "execute",
|
||||
"risk": "high",
|
||||
"description": "WMS 작업 시작",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "wms.work.read",
|
||||
"module": "WMS",
|
||||
"resource": "work",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "WMS 작업 Queue 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.telemetry.write",
|
||||
"module": "COMMON",
|
||||
"resource": "telemetry",
|
||||
"action": "write",
|
||||
"risk": "low",
|
||||
"description": "민감정보를 포함하지 않는 KBX 의미 단위 UX Telemetry 전송",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.ux.read",
|
||||
"module": "COMMON",
|
||||
"resource": "ux-metrics",
|
||||
"action": "read",
|
||||
"risk": "medium",
|
||||
"description": "KBX UX 품질·자동화 지표 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.experiment.evaluate",
|
||||
"module": "COMMON",
|
||||
"resource": "experiment",
|
||||
"action": "evaluate",
|
||||
"risk": "low",
|
||||
"description": "현재 사용자에 대한 안전한 UX 실험 Variant 평가",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.experiment.read",
|
||||
"module": "COMMON",
|
||||
"resource": "experiment",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "KBX UX 실험·점진배포 상태 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.experiment.manage",
|
||||
"module": "COMMON",
|
||||
"resource": "experiment",
|
||||
"action": "manage",
|
||||
"risk": "high",
|
||||
"description": "UX 실험 점진배포 비율 변경·일시중지·즉시 롤백",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.integration.read",
|
||||
"module": "COMMON",
|
||||
"resource": "integration",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "업무 외부연계 상태·시도 이력 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.integration.retry",
|
||||
"module": "COMMON",
|
||||
"resource": "integration",
|
||||
"action": "retry",
|
||||
"risk": "high",
|
||||
"description": "최종 실패한 idempotent 외부연계의 수동 재처리 예약",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.external-data.read",
|
||||
"module": "COMMON",
|
||||
"resource": "external-data",
|
||||
"action": "read",
|
||||
"risk": "low",
|
||||
"description": "외부 데이터셋의 출처·신선도·캐시 상태 조회",
|
||||
"presentation": "hide",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "common.external-data.refresh",
|
||||
"module": "COMMON",
|
||||
"resource": "external-data",
|
||||
"action": "refresh",
|
||||
"risk": "medium",
|
||||
"description": "승인된 외부 데이터셋의 명시적 재수집 요청",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.confirm",
|
||||
"module": "OMS",
|
||||
"resource": "order",
|
||||
"action": "confirm",
|
||||
"risk": "high",
|
||||
"description": "작성 주문 확정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
},
|
||||
{
|
||||
"id": "oms.order.write",
|
||||
"module": "OMS",
|
||||
"resource": "order",
|
||||
"action": "write",
|
||||
"risk": "medium",
|
||||
"description": "작성 상태 주문 수정",
|
||||
"presentation": "disable",
|
||||
"backendRequired": true
|
||||
}
|
||||
],
|
||||
"sensitiveDataPolicies": [
|
||||
{
|
||||
"id": "oms.order.recipient",
|
||||
"fields": [
|
||||
"receiverName",
|
||||
"phone",
|
||||
"postalCode",
|
||||
"address1",
|
||||
"address2"
|
||||
],
|
||||
"defaultExposure": "masked",
|
||||
"viewPermission": "oms.order.read",
|
||||
"revealPermission": "oms.order.recipient.unmask",
|
||||
"unmaskedExportPermission": "oms.order.recipient.export",
|
||||
"auditRequired": true,
|
||||
"aiExposure": "masked-only",
|
||||
"telemetryExposure": "never",
|
||||
"reasonRequired": false
|
||||
}
|
||||
],
|
||||
"ai": {
|
||||
"usePermission": "common.ai.use",
|
||||
"executePermission": "common.ai.execute",
|
||||
"executeRequiresProposalPermission": true,
|
||||
"defaultCapabilities": [
|
||||
"explain",
|
||||
"suggest",
|
||||
"draft"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,525 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"contractVersion": "1.0.0",
|
||||
"principles": {
|
||||
"secretsNeverCommitted": true,
|
||||
"failFastOnInvalidRuntimeConfiguration": true,
|
||||
"productionUnsafeDefaultsForbidden": true,
|
||||
"staticConfigurationSeparatedFromDynamicRuntimeState": true,
|
||||
"databaseMigrationsArePreDeployInProduction": true,
|
||||
"providerEndpointOverridesForbiddenInProduction": true,
|
||||
"configurationFingerprintExcludesSecrets": true,
|
||||
"generatedExamplesNeverContainSecretValues": true,
|
||||
"environmentPromotionUsesTheSameArtifact": true,
|
||||
"runtimeConfigMustNotReplaceDomainRules": true
|
||||
},
|
||||
"sourcePrecedence": [
|
||||
"defaults",
|
||||
"appsettings",
|
||||
"environment-specific-appsettings",
|
||||
"environment",
|
||||
"secret-store",
|
||||
"command-line"
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"key": "Kbx:Runtime:Environment",
|
||||
"env": "KBX__Runtime__Environment",
|
||||
"category": "runtime",
|
||||
"type": "enum",
|
||||
"allowedValues": [
|
||||
"Development",
|
||||
"Test",
|
||||
"Staging",
|
||||
"Production"
|
||||
],
|
||||
"default": "Development",
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": [
|
||||
"Development",
|
||||
"Test",
|
||||
"Staging",
|
||||
"Production"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Runtime:ReadOnly",
|
||||
"env": "KBX__Runtime__ReadOnly",
|
||||
"category": "runtime",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"secret": false,
|
||||
"restartRequired": false,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "ConnectionStrings:Main",
|
||||
"env": "ConnectionStrings__Main",
|
||||
"category": "database",
|
||||
"type": "connection-string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredIn": [
|
||||
"Development",
|
||||
"Test",
|
||||
"Staging",
|
||||
"Production"
|
||||
],
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Database:MigrationsMode",
|
||||
"env": "KBX__Database__MigrationsMode",
|
||||
"category": "database",
|
||||
"type": "enum",
|
||||
"allowedValues": [
|
||||
"validate",
|
||||
"startup-apply",
|
||||
"predeploy"
|
||||
],
|
||||
"default": "validate",
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": [
|
||||
"Development",
|
||||
"Test",
|
||||
"Staging",
|
||||
"Production"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Database:CommandTimeoutSeconds",
|
||||
"env": "KBX__Database__CommandTimeoutSeconds",
|
||||
"category": "database",
|
||||
"type": "integer",
|
||||
"default": 30,
|
||||
"minimum": 1,
|
||||
"maximum": 300,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Hangfire:Enabled",
|
||||
"env": "KBX__Hangfire__Enabled",
|
||||
"category": "background-jobs",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Hangfire:WorkerCount",
|
||||
"env": "KBX__Hangfire__WorkerCount",
|
||||
"category": "background-jobs",
|
||||
"type": "integer",
|
||||
"default": 4,
|
||||
"minimum": 1,
|
||||
"maximum": 64,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:SignalR:Enabled",
|
||||
"env": "KBX__SignalR__Enabled",
|
||||
"category": "realtime",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Outbox:DispatcherEnabled",
|
||||
"env": "KBX__Outbox__DispatcherEnabled",
|
||||
"category": "messaging",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Inbox:CleanupEnabled",
|
||||
"env": "KBX__Inbox__CleanupEnabled",
|
||||
"category": "messaging",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Integration:DispatcherEnabled",
|
||||
"env": "KBX__Integration__DispatcherEnabled",
|
||||
"category": "integration",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:ExternalData:RefreshEnabled",
|
||||
"env": "KBX__ExternalData__RefreshEnabled",
|
||||
"category": "external-data",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:ExternalData:ObservationRetentionEnabled",
|
||||
"env": "KBX__ExternalData__ObservationRetentionEnabled",
|
||||
"category": "external-data",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Experiments:Enabled",
|
||||
"env": "KBX__Experiments__Enabled",
|
||||
"category": "experiments",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": false,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Logging:MinimumLevel",
|
||||
"env": "KBX__Logging__MinimumLevel",
|
||||
"category": "logging",
|
||||
"type": "enum",
|
||||
"allowedValues": [
|
||||
"Debug",
|
||||
"Information",
|
||||
"Warning",
|
||||
"Error"
|
||||
],
|
||||
"default": "Information",
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Logging:JsonConsoleEnabled",
|
||||
"env": "KBX__Logging__JsonConsoleEnabled",
|
||||
"category": "logging",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Telemetry:Enabled",
|
||||
"env": "KBX__Telemetry__Enabled",
|
||||
"category": "observability",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Telemetry:OtlpEndpoint",
|
||||
"env": "KBX__Telemetry__OtlpEndpoint",
|
||||
"category": "observability",
|
||||
"type": "uri",
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Telegram:Enabled",
|
||||
"env": "KBX__Telegram__Enabled",
|
||||
"category": "alerting",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Telegram:BotToken",
|
||||
"env": "KBX__Telegram__BotToken",
|
||||
"category": "alerting",
|
||||
"type": "string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "Kbx:Telegram:Enabled",
|
||||
"equals": true
|
||||
},
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Telegram:ChatId",
|
||||
"env": "KBX__Telegram__ChatId",
|
||||
"category": "alerting",
|
||||
"type": "string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "Kbx:Telegram:Enabled",
|
||||
"equals": true
|
||||
},
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:Krx:Enabled",
|
||||
"env": "ExternalProviders__Krx__Enabled",
|
||||
"category": "provider",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:Krx:AuthKey",
|
||||
"env": "ExternalProviders__Krx__AuthKey",
|
||||
"category": "provider",
|
||||
"type": "string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "ExternalProviders:Krx:Enabled",
|
||||
"equals": true
|
||||
},
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:OpenDart:Enabled",
|
||||
"env": "ExternalProviders__OpenDart__Enabled",
|
||||
"category": "provider",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:OpenDart:ApiKey",
|
||||
"env": "ExternalProviders__OpenDart__ApiKey",
|
||||
"category": "provider",
|
||||
"type": "string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "ExternalProviders:OpenDart:Enabled",
|
||||
"equals": true
|
||||
},
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:Kis:Enabled",
|
||||
"env": "ExternalProviders__Kis__Enabled",
|
||||
"category": "provider",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:Kis:Environment",
|
||||
"env": "ExternalProviders__Kis__Environment",
|
||||
"category": "provider",
|
||||
"type": "enum",
|
||||
"allowedValues": [
|
||||
"sandbox",
|
||||
"production"
|
||||
],
|
||||
"default": "sandbox",
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "ExternalProviders:Kis:Enabled",
|
||||
"equals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:Kis:AppKey",
|
||||
"env": "ExternalProviders__Kis__AppKey",
|
||||
"category": "provider",
|
||||
"type": "string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "ExternalProviders:Kis:Enabled",
|
||||
"equals": true
|
||||
},
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "ExternalProviders:Kis:AppSecret",
|
||||
"env": "ExternalProviders__Kis__AppSecret",
|
||||
"category": "provider",
|
||||
"type": "string",
|
||||
"secret": true,
|
||||
"restartRequired": true,
|
||||
"requiredWhen": {
|
||||
"key": "ExternalProviders:Kis:Enabled",
|
||||
"equals": true
|
||||
},
|
||||
"allowedSources": [
|
||||
"environment",
|
||||
"secret-store",
|
||||
"user-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Security:RequireHttps",
|
||||
"env": "KBX__Security__RequireHttps",
|
||||
"category": "security",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Health:ReadinessEnabled",
|
||||
"env": "KBX__Health__ReadinessEnabled",
|
||||
"category": "runtime",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Import:MaxUploadBytes",
|
||||
"env": "KBX__Import__MaxUploadBytes",
|
||||
"category": "import",
|
||||
"type": "integer",
|
||||
"default": 52428800,
|
||||
"minimum": 1048576,
|
||||
"maximum": 209715200,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
},
|
||||
{
|
||||
"key": "Kbx:Import:MaxRows",
|
||||
"env": "KBX__Import__MaxRows",
|
||||
"category": "import",
|
||||
"type": "integer",
|
||||
"default": 100000,
|
||||
"minimum": 1,
|
||||
"maximum": 1000000,
|
||||
"secret": false,
|
||||
"restartRequired": true,
|
||||
"requiredIn": []
|
||||
}
|
||||
],
|
||||
"environments": [
|
||||
{
|
||||
"id": "Development",
|
||||
"artifactPromotion": false,
|
||||
"secretSources": [
|
||||
"user-secrets",
|
||||
"environment"
|
||||
],
|
||||
"migrationStrategy": "startup-apply-allowed",
|
||||
"providerNetwork": "opt-in",
|
||||
"requireHttps": false,
|
||||
"providerEndpointOverrideAllowed": true,
|
||||
"requiredGates": [
|
||||
"static-governance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Test",
|
||||
"artifactPromotion": false,
|
||||
"secretSources": [
|
||||
"environment"
|
||||
],
|
||||
"migrationStrategy": "ephemeral-apply",
|
||||
"providerNetwork": "forbidden",
|
||||
"requireHttps": false,
|
||||
"providerEndpointOverrideAllowed": true,
|
||||
"requiredGates": [
|
||||
"static-governance",
|
||||
"build",
|
||||
"unit",
|
||||
"integration",
|
||||
"scenario"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Staging",
|
||||
"artifactPromotion": true,
|
||||
"secretSources": [
|
||||
"secret-store",
|
||||
"environment"
|
||||
],
|
||||
"migrationStrategy": "predeploy",
|
||||
"providerNetwork": "opt-in",
|
||||
"requireHttps": true,
|
||||
"providerEndpointOverrideAllowed": false,
|
||||
"requiredGates": [
|
||||
"static-governance",
|
||||
"build",
|
||||
"unit",
|
||||
"integration",
|
||||
"scenario",
|
||||
"migration-dry-run"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Production",
|
||||
"artifactPromotion": true,
|
||||
"secretSources": [
|
||||
"secret-store",
|
||||
"environment"
|
||||
],
|
||||
"migrationStrategy": "predeploy",
|
||||
"providerNetwork": "opt-in",
|
||||
"requireHttps": true,
|
||||
"providerEndpointOverrideAllowed": false,
|
||||
"requiredGates": [
|
||||
"static-governance",
|
||||
"build",
|
||||
"unit",
|
||||
"integration",
|
||||
"scenario",
|
||||
"migration-dry-run",
|
||||
"configuration-validation",
|
||||
"release-governance"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"experimentVersion": "1.0.0",
|
||||
"principles": {
|
||||
"purpose": "controlled-ux-rollout-and-measurement",
|
||||
"serverAuthoritative": true,
|
||||
"stableAssignment": true,
|
||||
"exposureAfterRender": true,
|
||||
"killSwitchRequired": true,
|
||||
"maxRunningExperimentsPerScreen": 1,
|
||||
"safeUxOnly": true,
|
||||
"automaticRollbackOnGuardrailBreach": true,
|
||||
"statisticalClaim": "operational-threshold-only; do not claim statistical significance",
|
||||
"allowedSurfaces": [
|
||||
"layout",
|
||||
"information-emphasis",
|
||||
"default-filter",
|
||||
"navigation",
|
||||
"copy"
|
||||
],
|
||||
"prohibitedScopes": [
|
||||
"permission",
|
||||
"sensitive-data",
|
||||
"domain-rule",
|
||||
"validation",
|
||||
"idempotency",
|
||||
"workflow-safety",
|
||||
"wms-scan-rule",
|
||||
"inventory-truth"
|
||||
]
|
||||
},
|
||||
"featureFlags": [
|
||||
{
|
||||
"id": "oms.order-list.exception-summary-v2",
|
||||
"screenId": "OMS-ORD-001",
|
||||
"surface": "information-emphasis",
|
||||
"description": "기존 주문 Quick Filter를 이동시키지 않고 확인 필요 예외 요약을 보조적으로 노출하는 되돌릴 수 있는 UX 변경",
|
||||
"defaultVariant": "control",
|
||||
"killSwitch": true,
|
||||
"owner": "KBX"
|
||||
}
|
||||
],
|
||||
"experiments": [
|
||||
{
|
||||
"id": "exp.oms.order-list.exception-summary-v2",
|
||||
"flagId": "oms.order-list.exception-summary-v2",
|
||||
"screenId": "OMS-ORD-001",
|
||||
"state": "draft",
|
||||
"rolloutPercent": 0,
|
||||
"minExposurePerVariant": 200,
|
||||
"variants": [
|
||||
{
|
||||
"key": "control",
|
||||
"weight": 50
|
||||
},
|
||||
{
|
||||
"key": "exception-summary",
|
||||
"weight": 50
|
||||
}
|
||||
],
|
||||
"primaryMetric": {
|
||||
"key": "semantic_interactions_per_task",
|
||||
"direction": "lower",
|
||||
"minimumImprovementPercent": 10
|
||||
},
|
||||
"guardrails": [
|
||||
{
|
||||
"key": "task_completion_time_ms",
|
||||
"statistic": "p95",
|
||||
"maxRegressionPercent": 20
|
||||
},
|
||||
{
|
||||
"key": "validation_failure_rate",
|
||||
"statistic": "rate",
|
||||
"maxAbsoluteRegressionPercentagePoints": 2
|
||||
}
|
||||
],
|
||||
"globalGuardrails": [
|
||||
{
|
||||
"key": "manual_intervention_rate",
|
||||
"maxAbsoluteRegressionPercentagePoints": 0.5
|
||||
}
|
||||
],
|
||||
"notes": "Reference experiment only. v17 ships at draft/0%; rollout requires an explicit runtime decision and can be killed immediately."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"contractVersion": "1.0.0",
|
||||
"principles": {
|
||||
"externalProviderIsNotDomainTruth": true,
|
||||
"normalizedProjectionBeforeUi": true,
|
||||
"provenanceAlwaysVisible": true,
|
||||
"sourceObservedReceivedIngestedAreSeparate": true,
|
||||
"staleDataNeverLooksFresh": true,
|
||||
"rawPayloadRetentionRequiresExplicitPolicy": true,
|
||||
"payloadHashForReproducibility": true,
|
||||
"providerSpecificFieldsDoNotLeakIntoBusinessScreens": true,
|
||||
"cachePolicyIsKbxPolicyNotProviderFact": true
|
||||
},
|
||||
"datasets": [
|
||||
{
|
||||
"id": "dataset.opendart.company-profile",
|
||||
"providerId": "provider.opendart",
|
||||
"providerOperationId": "opendart.company",
|
||||
"canonicalType": "company-profile",
|
||||
"normalizer": "OpenDartCompanyProfileNormalizer",
|
||||
"normalizerVersion": "1.0.0",
|
||||
"cacheKeyFields": [
|
||||
"corpCode"
|
||||
],
|
||||
"freshness": {
|
||||
"mode": "stale-while-revalidate",
|
||||
"freshForSeconds": 86400,
|
||||
"maxStaleSeconds": 604800,
|
||||
"backgroundRefresh": true
|
||||
},
|
||||
"snapshot": {
|
||||
"rawRetention": "hash-only",
|
||||
"normalizedRetentionDays": 365
|
||||
},
|
||||
"ui": {
|
||||
"sourceLabel": "OPENDART",
|
||||
"showProviderObservedAt": false,
|
||||
"showReceivedAt": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dataset.opendart.disclosures",
|
||||
"providerId": "provider.opendart",
|
||||
"providerOperationId": "opendart.disclosures",
|
||||
"canonicalType": "disclosure-list",
|
||||
"normalizer": "OpenDartDisclosureListNormalizer",
|
||||
"normalizerVersion": "1.0.0",
|
||||
"cacheKeyFields": [
|
||||
"corpCode",
|
||||
"beginDate",
|
||||
"endDate",
|
||||
"pageNo",
|
||||
"pageCount"
|
||||
],
|
||||
"freshness": {
|
||||
"mode": "stale-while-revalidate",
|
||||
"freshForSeconds": 300,
|
||||
"maxStaleSeconds": 3600,
|
||||
"backgroundRefresh": true
|
||||
},
|
||||
"snapshot": {
|
||||
"rawRetention": "hash-only",
|
||||
"normalizedRetentionDays": 90
|
||||
},
|
||||
"ui": {
|
||||
"sourceLabel": "OPENDART",
|
||||
"showProviderObservedAt": false,
|
||||
"showReceivedAt": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dataset.kis.domestic-stock.current-price",
|
||||
"providerId": "provider.kis.market-data",
|
||||
"providerOperationId": "kis.domestic-stock.current-price",
|
||||
"canonicalType": "market-price",
|
||||
"normalizer": "KisCurrentPriceNormalizer",
|
||||
"normalizerVersion": "1.0.0",
|
||||
"cacheKeyFields": [
|
||||
"marketDivisionCode",
|
||||
"stockCode",
|
||||
"environment"
|
||||
],
|
||||
"freshness": {
|
||||
"mode": "strict",
|
||||
"freshForSeconds": 3,
|
||||
"maxStaleSeconds": 0,
|
||||
"backgroundRefresh": false
|
||||
},
|
||||
"snapshot": {
|
||||
"rawRetention": "hash-only",
|
||||
"normalizedRetentionDays": 7
|
||||
},
|
||||
"ui": {
|
||||
"sourceLabel": "KIS",
|
||||
"showProviderObservedAt": false,
|
||||
"showReceivedAt": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dataset.krx.approved-service",
|
||||
"providerId": "provider.krx.openapi",
|
||||
"providerOperationId": "krx.approved-service.invoke",
|
||||
"canonicalType": "provider-defined",
|
||||
"normalizer": "registered-per-approved-service",
|
||||
"normalizerVersion": "provider-defined",
|
||||
"cacheKeyFields": [
|
||||
"serviceId",
|
||||
"querySignature"
|
||||
],
|
||||
"freshness": {
|
||||
"mode": "provider-defined",
|
||||
"freshForSeconds": null,
|
||||
"maxStaleSeconds": null,
|
||||
"backgroundRefresh": false,
|
||||
"requireExplicitServicePolicy": true
|
||||
},
|
||||
"snapshot": {
|
||||
"rawRetention": "hash-only",
|
||||
"normalizedRetentionDays": 30
|
||||
},
|
||||
"ui": {
|
||||
"sourceLabel": "KRX",
|
||||
"showProviderObservedAt": false,
|
||||
"showReceivedAt": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,707 @@
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"description": "KBX canonical field dictionary. Structural metadata only; domain business rules remain in server/domain code.",
|
||||
"fields": [
|
||||
{
|
||||
"key": "orderId",
|
||||
"label": "주문ID",
|
||||
"aliases": [
|
||||
"OrderId"
|
||||
],
|
||||
"dataType": "code",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "orderNo",
|
||||
"label": "주문번호",
|
||||
"aliases": [
|
||||
"OrderNo",
|
||||
"주문ID"
|
||||
],
|
||||
"dataType": "code",
|
||||
"required": true,
|
||||
"maxLength": 50,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "orderDate",
|
||||
"label": "주문일",
|
||||
"aliases": [
|
||||
"주문일자",
|
||||
"OrderDate"
|
||||
],
|
||||
"dataType": "date",
|
||||
"required": true,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "orderedAt",
|
||||
"label": "주문일시",
|
||||
"aliases": [
|
||||
"OrderedAt",
|
||||
"주문시간"
|
||||
],
|
||||
"dataType": "datetime",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "channelId",
|
||||
"label": "판매채널ID",
|
||||
"aliases": [
|
||||
"ChannelId"
|
||||
],
|
||||
"dataType": "lookup",
|
||||
"lookupEntity": "salesChannel",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "channelName",
|
||||
"label": "판매채널",
|
||||
"aliases": [
|
||||
"ChannelName",
|
||||
"채널"
|
||||
],
|
||||
"dataType": "text",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "customerId",
|
||||
"label": "거래처ID",
|
||||
"aliases": [
|
||||
"CustomerId"
|
||||
],
|
||||
"dataType": "lookup",
|
||||
"lookupEntity": "customer",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "customerCode",
|
||||
"label": "거래처코드",
|
||||
"aliases": [
|
||||
"거래처",
|
||||
"업체코드",
|
||||
"CustomerCode"
|
||||
],
|
||||
"dataType": "code",
|
||||
"required": true,
|
||||
"maxLength": 50,
|
||||
"lookupEntity": "customer",
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "customerName",
|
||||
"label": "거래처명",
|
||||
"aliases": [
|
||||
"CustomerName",
|
||||
"업체명"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 200,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "receiverName",
|
||||
"label": "수취인",
|
||||
"aliases": [
|
||||
"받는분",
|
||||
"수령인",
|
||||
"ReceiverName"
|
||||
],
|
||||
"dataType": "text",
|
||||
"required": true,
|
||||
"maxLength": 100,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": true,
|
||||
"masking": "name"
|
||||
},
|
||||
{
|
||||
"key": "phone",
|
||||
"label": "연락처",
|
||||
"aliases": [
|
||||
"휴대폰",
|
||||
"전화번호",
|
||||
"Phone"
|
||||
],
|
||||
"dataType": "text",
|
||||
"required": true,
|
||||
"maxLength": 50,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": true,
|
||||
"masking": "phone"
|
||||
},
|
||||
{
|
||||
"key": "postalCode",
|
||||
"label": "우편번호",
|
||||
"aliases": [
|
||||
"ZipCode",
|
||||
"PostalCode"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 20,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": true,
|
||||
"masking": "address"
|
||||
},
|
||||
{
|
||||
"key": "address1",
|
||||
"label": "주소",
|
||||
"aliases": [
|
||||
"기본주소",
|
||||
"배송주소",
|
||||
"Address1"
|
||||
],
|
||||
"dataType": "text",
|
||||
"required": true,
|
||||
"maxLength": 500,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": true,
|
||||
"masking": "address"
|
||||
},
|
||||
{
|
||||
"key": "address2",
|
||||
"label": "상세주소",
|
||||
"aliases": [
|
||||
"주소2",
|
||||
"Address2"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 500,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": true,
|
||||
"masking": "address"
|
||||
},
|
||||
{
|
||||
"key": "itemId",
|
||||
"label": "품목ID",
|
||||
"aliases": [
|
||||
"ItemId"
|
||||
],
|
||||
"dataType": "lookup",
|
||||
"lookupEntity": "item",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "itemCode",
|
||||
"label": "품목코드",
|
||||
"aliases": [
|
||||
"상품코드",
|
||||
"SKU",
|
||||
"ItemCode"
|
||||
],
|
||||
"dataType": "code",
|
||||
"required": true,
|
||||
"maxLength": 80,
|
||||
"lookupEntity": "item",
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "itemName",
|
||||
"label": "품목명",
|
||||
"aliases": [
|
||||
"상품명",
|
||||
"ItemName"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 300,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "itemSummary",
|
||||
"label": "대표상품",
|
||||
"aliases": [
|
||||
"ItemSummary"
|
||||
],
|
||||
"dataType": "text",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "barcode",
|
||||
"label": "바코드",
|
||||
"aliases": [
|
||||
"Barcode",
|
||||
"EAN",
|
||||
"JAN"
|
||||
],
|
||||
"dataType": "code",
|
||||
"maxLength": 100,
|
||||
"lookupEntity": "item",
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "warehouseId",
|
||||
"label": "창고ID",
|
||||
"aliases": [
|
||||
"WarehouseId"
|
||||
],
|
||||
"dataType": "lookup",
|
||||
"lookupEntity": "warehouse",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "warehouseCode",
|
||||
"label": "창고코드",
|
||||
"aliases": [
|
||||
"창고",
|
||||
"창고코드",
|
||||
"출고창고",
|
||||
"WarehouseCode"
|
||||
],
|
||||
"dataType": "code",
|
||||
"required": true,
|
||||
"maxLength": 50,
|
||||
"lookupEntity": "warehouse",
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "warehouseName",
|
||||
"label": "창고명",
|
||||
"aliases": [
|
||||
"WarehouseName"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 200,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "locationId",
|
||||
"label": "로케이션ID",
|
||||
"aliases": [
|
||||
"LocationId"
|
||||
],
|
||||
"dataType": "lookup",
|
||||
"lookupEntity": "location",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "locationCode",
|
||||
"label": "로케이션",
|
||||
"aliases": [
|
||||
"Location",
|
||||
"LocationCode",
|
||||
"위치"
|
||||
],
|
||||
"dataType": "code",
|
||||
"maxLength": 80,
|
||||
"lookupEntity": "location",
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "quantity",
|
||||
"label": "수량",
|
||||
"aliases": [
|
||||
"Qty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "orderQty",
|
||||
"label": "주문수량",
|
||||
"aliases": [
|
||||
"주문수량",
|
||||
"수량",
|
||||
"Qty",
|
||||
"OrderQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "totalQty",
|
||||
"label": "총수량",
|
||||
"aliases": [
|
||||
"TotalQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "allocatedQty",
|
||||
"label": "할당수량",
|
||||
"aliases": [
|
||||
"AllocatedQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "pickedQty",
|
||||
"label": "피킹수량",
|
||||
"aliases": [
|
||||
"PickedQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "shippedQty",
|
||||
"label": "출고수량",
|
||||
"aliases": [
|
||||
"ShippedQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "onHandQty",
|
||||
"label": "현재고",
|
||||
"aliases": [
|
||||
"OnHandQty",
|
||||
"장부재고"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "availableQty",
|
||||
"label": "가용재고",
|
||||
"aliases": [
|
||||
"AvailableQty",
|
||||
"출고가능수량"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "holdQty",
|
||||
"label": "보류수량",
|
||||
"aliases": [
|
||||
"HoldQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "damagedQty",
|
||||
"label": "불량수량",
|
||||
"aliases": [
|
||||
"DamagedQty"
|
||||
],
|
||||
"dataType": "quantity",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "effectiveDate",
|
||||
"label": "적용일",
|
||||
"aliases": [
|
||||
"EffectiveDate",
|
||||
"시작일",
|
||||
"적용시작일"
|
||||
],
|
||||
"dataType": "date",
|
||||
"required": true,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "unitPrice",
|
||||
"label": "단가",
|
||||
"aliases": [
|
||||
"판매단가",
|
||||
"UnitPrice"
|
||||
],
|
||||
"dataType": "money",
|
||||
"precision": 18,
|
||||
"scale": 4,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "amount",
|
||||
"label": "금액",
|
||||
"aliases": [
|
||||
"Amount",
|
||||
"주문금액"
|
||||
],
|
||||
"dataType": "money",
|
||||
"precision": 18,
|
||||
"scale": 2,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "remark",
|
||||
"label": "비고",
|
||||
"aliases": [
|
||||
"메모",
|
||||
"배송메모",
|
||||
"Remark"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 500,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "lotNo",
|
||||
"label": "LOT",
|
||||
"aliases": [
|
||||
"LotNo",
|
||||
"LOT번호"
|
||||
],
|
||||
"dataType": "code",
|
||||
"maxLength": 100,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "expiryDate",
|
||||
"label": "유통기한",
|
||||
"aliases": [
|
||||
"ExpiryDate",
|
||||
"ExpirationDate"
|
||||
],
|
||||
"dataType": "date",
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "status",
|
||||
"label": "상태",
|
||||
"aliases": [
|
||||
"Status"
|
||||
],
|
||||
"dataType": "status",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "version",
|
||||
"label": "버전",
|
||||
"aliases": [
|
||||
"Version",
|
||||
"RowVersion"
|
||||
],
|
||||
"dataType": "integer",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": false,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "createdAt",
|
||||
"label": "등록일시",
|
||||
"aliases": [
|
||||
"CreatedAt"
|
||||
],
|
||||
"dataType": "datetime",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "updatedAt",
|
||||
"label": "수정일시",
|
||||
"aliases": [
|
||||
"UpdatedAt"
|
||||
],
|
||||
"dataType": "datetime",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "createdBy",
|
||||
"label": "등록자",
|
||||
"aliases": [
|
||||
"CreatedBy"
|
||||
],
|
||||
"dataType": "text",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "updatedBy",
|
||||
"label": "수정자",
|
||||
"aliases": [
|
||||
"UpdatedBy"
|
||||
],
|
||||
"dataType": "text",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "referenceNo",
|
||||
"label": "참조번호",
|
||||
"aliases": [
|
||||
"ReferenceNo"
|
||||
],
|
||||
"dataType": "code",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "ownerName",
|
||||
"label": "담당자",
|
||||
"aliases": [
|
||||
"OwnerName",
|
||||
"담당"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 100,
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "occurredAt",
|
||||
"label": "발생시각",
|
||||
"aliases": [
|
||||
"OccurredAt"
|
||||
],
|
||||
"dataType": "datetime",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "exceptionCount",
|
||||
"label": "예외건수",
|
||||
"aliases": [
|
||||
"ExceptionCount",
|
||||
"오류건수"
|
||||
],
|
||||
"dataType": "integer",
|
||||
"readonly": true,
|
||||
"importable": false,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
},
|
||||
{
|
||||
"key": "specification",
|
||||
"label": "규격",
|
||||
"aliases": [
|
||||
"Specification",
|
||||
"Spec"
|
||||
],
|
||||
"dataType": "text",
|
||||
"maxLength": 200,
|
||||
"importable": true,
|
||||
"exportable": true,
|
||||
"sensitive": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "KBX Field Dictionary",
|
||||
"type": "object",
|
||||
"required": ["version", "fields"],
|
||||
"properties": {
|
||||
"version": {"type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$"},
|
||||
"description": {"type": "string"},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["key", "label", "dataType", "importable", "exportable", "sensitive"],
|
||||
"properties": {
|
||||
"key": {"type": "string", "pattern": "^[a-z][A-Za-z0-9]*$"},
|
||||
"label": {"type": "string", "minLength": 1},
|
||||
"aliases": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
||||
"dataType": {"enum": ["text","code","integer","decimal","quantity","money","date","datetime","boolean","lookup","status"]},
|
||||
"required": {"type": "boolean"},
|
||||
"maxLength": {"type": "integer", "minimum": 1},
|
||||
"precision": {"type": "integer", "minimum": 1},
|
||||
"scale": {"type": "integer", "minimum": 0},
|
||||
"lookupEntity": {"type": "string"},
|
||||
"readonly": {"type": "boolean"},
|
||||
"importable": {"type": "boolean"},
|
||||
"exportable": {"type": "boolean"},
|
||||
"sensitive": {"type": "boolean"},
|
||||
"masking": {"enum": ["name","phone","address","partial"]},
|
||||
"helpText": {"type": "string"},
|
||||
"deprecated": {"type": "boolean"},
|
||||
"replacementKey": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"integrationVersion": "1.0.0",
|
||||
"principles": {
|
||||
"businessStateSeparatedFromIntegrationState": true,
|
||||
"atLeastOnceRequiresIdempotency": true,
|
||||
"transientRetryOnly": true,
|
||||
"hangfireOwnsLongRetry": true,
|
||||
"pollyOwnsShortTransientResilience": true,
|
||||
"signalRIsNotSourceOfTruth": true,
|
||||
"terminalFailuresCreateOperationsException": true,
|
||||
"userNeverNeedsToRepeatBusinessCommandForIntegrationFailure": true
|
||||
},
|
||||
"states": [
|
||||
"queued",
|
||||
"delivering",
|
||||
"retrying",
|
||||
"delivered",
|
||||
"failed",
|
||||
"suspended"
|
||||
],
|
||||
"integrations": [
|
||||
{
|
||||
"id": "integration.oms.wms.dispatch",
|
||||
"title": "OMS → WMS 출고지시 전달",
|
||||
"ownerModule": "OMS",
|
||||
"direction": "outbound",
|
||||
"transport": "outbox-http",
|
||||
"criticality": "high",
|
||||
"sourceEvent": "OrderShipmentRequested",
|
||||
"target": "WMS",
|
||||
"delivery": "at-least-once",
|
||||
"ordering": "per-aggregate",
|
||||
"idempotency": "event-id",
|
||||
"timeoutMs": 3000,
|
||||
"shortRetry": {
|
||||
"maxRetryAttempts": 2,
|
||||
"baseDelayMs": 250,
|
||||
"backoff": "exponential"
|
||||
},
|
||||
"longRetry": {
|
||||
"scheduler": "hangfire",
|
||||
"maxAttempts": 8,
|
||||
"scheduleSeconds": [
|
||||
10,
|
||||
30,
|
||||
120,
|
||||
300,
|
||||
900,
|
||||
1800,
|
||||
3600,
|
||||
7200
|
||||
]
|
||||
},
|
||||
"circuitBreaker": {
|
||||
"failureRatio": 0.5,
|
||||
"samplingSeconds": 30,
|
||||
"minimumThroughput": 10,
|
||||
"breakSeconds": 30
|
||||
},
|
||||
"retryable": [
|
||||
"network",
|
||||
"timeout",
|
||||
"http-408",
|
||||
"http-429",
|
||||
"http-5xx",
|
||||
"circuit-open"
|
||||
],
|
||||
"permanent": [
|
||||
"contract-invalid",
|
||||
"http-400",
|
||||
"http-401",
|
||||
"http-403",
|
||||
"http-404",
|
||||
"domain-rejected"
|
||||
],
|
||||
"terminalAction": "operations-exception",
|
||||
"userVisible": true
|
||||
},
|
||||
{
|
||||
"id": "integration.wms.oms.picking-result",
|
||||
"title": "WMS → OMS 피킹결과 전달",
|
||||
"ownerModule": "WMS",
|
||||
"direction": "outbound",
|
||||
"transport": "outbox-http",
|
||||
"criticality": "high",
|
||||
"sourceEvent": "PickingCompleted",
|
||||
"target": "OMS",
|
||||
"delivery": "at-least-once",
|
||||
"ordering": "per-aggregate",
|
||||
"idempotency": "event-id",
|
||||
"timeoutMs": 3000,
|
||||
"shortRetry": {
|
||||
"maxRetryAttempts": 2,
|
||||
"baseDelayMs": 250,
|
||||
"backoff": "exponential"
|
||||
},
|
||||
"longRetry": {
|
||||
"scheduler": "hangfire",
|
||||
"maxAttempts": 8,
|
||||
"scheduleSeconds": [
|
||||
10,
|
||||
30,
|
||||
120,
|
||||
300,
|
||||
900,
|
||||
1800,
|
||||
3600,
|
||||
7200
|
||||
]
|
||||
},
|
||||
"circuitBreaker": {
|
||||
"failureRatio": 0.5,
|
||||
"samplingSeconds": 30,
|
||||
"minimumThroughput": 10,
|
||||
"breakSeconds": 30
|
||||
},
|
||||
"retryable": [
|
||||
"network",
|
||||
"timeout",
|
||||
"http-408",
|
||||
"http-429",
|
||||
"http-5xx",
|
||||
"circuit-open"
|
||||
],
|
||||
"permanent": [
|
||||
"contract-invalid",
|
||||
"http-400",
|
||||
"http-401",
|
||||
"http-403",
|
||||
"http-404",
|
||||
"domain-rejected"
|
||||
],
|
||||
"terminalAction": "operations-exception",
|
||||
"userVisible": true
|
||||
},
|
||||
{
|
||||
"id": "integration.carrier.tracking",
|
||||
"title": "배송사 송장/배송상태 연계",
|
||||
"ownerModule": "OMS",
|
||||
"direction": "outbound",
|
||||
"transport": "outbox-http",
|
||||
"criticality": "medium",
|
||||
"sourceEvent": "TrackingSubmissionRequested",
|
||||
"target": "CarrierGateway",
|
||||
"delivery": "at-least-once",
|
||||
"ordering": "none",
|
||||
"idempotency": "business-key",
|
||||
"timeoutMs": 5000,
|
||||
"shortRetry": {
|
||||
"maxRetryAttempts": 2,
|
||||
"baseDelayMs": 500,
|
||||
"backoff": "exponential"
|
||||
},
|
||||
"longRetry": {
|
||||
"scheduler": "hangfire",
|
||||
"maxAttempts": 6,
|
||||
"scheduleSeconds": [
|
||||
30,
|
||||
120,
|
||||
600,
|
||||
1800,
|
||||
3600,
|
||||
7200
|
||||
]
|
||||
},
|
||||
"circuitBreaker": {
|
||||
"failureRatio": 0.5,
|
||||
"samplingSeconds": 60,
|
||||
"minimumThroughput": 10,
|
||||
"breakSeconds": 60
|
||||
},
|
||||
"retryable": [
|
||||
"network",
|
||||
"timeout",
|
||||
"http-408",
|
||||
"http-429",
|
||||
"http-5xx",
|
||||
"circuit-open"
|
||||
],
|
||||
"permanent": [
|
||||
"contract-invalid",
|
||||
"http-400",
|
||||
"http-401",
|
||||
"http-403",
|
||||
"http-404",
|
||||
"domain-rejected"
|
||||
],
|
||||
"terminalAction": "operations-exception",
|
||||
"userVisible": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://kbx.local/contracts/problems/kbx.problem.schema.json",
|
||||
"title": "KBX Problem",
|
||||
"oneOf": [
|
||||
{ "$ref": "#/$defs/validation" },
|
||||
{ "$ref": "#/$defs/businessRule" },
|
||||
{ "$ref": "#/$defs/conflict" },
|
||||
{ "$ref": "#/$defs/permission" },
|
||||
{ "$ref": "#/$defs/notFound" },
|
||||
{ "$ref": "#/$defs/integration" },
|
||||
{ "$ref": "#/$defs/system" }
|
||||
],
|
||||
"$defs": {
|
||||
"base": {
|
||||
"type": "object",
|
||||
"required": ["type", "title"],
|
||||
"properties": {
|
||||
"type": { "type": "string" },
|
||||
"title": { "type": "string", "minLength": 1 },
|
||||
"detail": { "type": ["string", "null"] },
|
||||
"correlationId": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"action": {
|
||||
"type": "object",
|
||||
"required": ["id", "label"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"label": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"validationError": {
|
||||
"type": "object",
|
||||
"required": ["code", "message"],
|
||||
"properties": {
|
||||
"field": { "type": ["string", "null"] },
|
||||
"rowKey": { "type": ["string", "null"] },
|
||||
"code": { "type": "string", "minLength": 1 },
|
||||
"message": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"validation": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "errors"],
|
||||
"properties": {
|
||||
"type": { "const": "validation" },
|
||||
"errors": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/validationError" } }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"businessRule": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "code"],
|
||||
"properties": {
|
||||
"type": { "const": "business-rule" },
|
||||
"code": { "type": "string", "minLength": 1 },
|
||||
"actions": { "type": "array", "items": { "$ref": "#/$defs/action" } }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"conflict": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "code"],
|
||||
"properties": {
|
||||
"type": { "const": "conflict" },
|
||||
"code": { "type": "string", "minLength": 1 },
|
||||
"currentVersion": { "type": ["integer", "null"], "minimum": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"permission": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "code"],
|
||||
"properties": {
|
||||
"type": { "const": "permission" },
|
||||
"code": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"notFound": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "code"],
|
||||
"properties": {
|
||||
"type": { "const": "not-found" },
|
||||
"code": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"integration": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "code", "retryable"],
|
||||
"properties": {
|
||||
"type": { "const": "integration" },
|
||||
"code": { "type": "string", "minLength": 1 },
|
||||
"retryable": { "type": "boolean" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"system": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/base" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type", "code", "correlationId"],
|
||||
"properties": {
|
||||
"type": { "const": "system" },
|
||||
"code": { "type": "string", "minLength": 1 },
|
||||
"correlationId": { "type": "string", "minLength": 1 },
|
||||
"retryable": { "type": "boolean" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"providerVersion": "1.0.0",
|
||||
"principles": {
|
||||
"officialSourcesOnly": true,
|
||||
"secretsNeverEnterUiTelemetryOrLogs": true,
|
||||
"providerFactsSeparatedFromKbxPolicy": true,
|
||||
"unknownLimitsAreNotInvented": true,
|
||||
"readOnlyByDefault": true,
|
||||
"domainWritesRequireSeparateIntegrationContract": true,
|
||||
"providerErrorNeverBecomesBusinessTruth": true
|
||||
},
|
||||
"providers": [
|
||||
{
|
||||
"id": "provider.krx.openapi",
|
||||
"title": "KRX Data Marketplace OPEN API",
|
||||
"ownerModule": "COMMON",
|
||||
"purpose": "market-data-readonly",
|
||||
"mutationAllowed": false,
|
||||
"officialSources": [
|
||||
"https://openapi.krx.co.kr/contents/OPP/INFO/OPPINFO003.jsp",
|
||||
"https://openapi.krx.co.kr/contents/OPP/INFO/service/OPPINFO004.cmd"
|
||||
],
|
||||
"official": {
|
||||
"approvalRequired": true,
|
||||
"authentication": {
|
||||
"type": "header-api-key",
|
||||
"headerName": "AUTH_KEY"
|
||||
},
|
||||
"serviceUrlPolicy": "service-specific-from-approved-KRX-definition",
|
||||
"dataAvailabilityNote": "서비스 목록은 다수 데이터에 대해 2010년 이후 제공범위를 안내함",
|
||||
"numericRateLimit": null
|
||||
},
|
||||
"kbxPolicy": {
|
||||
"allowedHostSuffix": ".krx.co.kr",
|
||||
"credentialKey": "ExternalProviders:Krx:AuthKey",
|
||||
"maxConcurrency": 2,
|
||||
"timeoutMs": 5000,
|
||||
"retryHttpStatuses": [
|
||||
408,
|
||||
429,
|
||||
500,
|
||||
502,
|
||||
503,
|
||||
504
|
||||
],
|
||||
"maxRetryAttempts": 1,
|
||||
"serviceDefinitionRequired": true,
|
||||
"cacheable": true
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"id": "krx.approved-service.invoke",
|
||||
"method": "provider-defined-read",
|
||||
"path": "provider-defined",
|
||||
"response": "json-or-xml",
|
||||
"notes": "실제 URL/메서드는 KRX에서 승인된 개별 서비스 명세를 구성값으로 등록. 저장소에서 추정하지 않음."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "provider.opendart",
|
||||
"title": "금융감독원 OPENDART OpenAPI",
|
||||
"ownerModule": "COMMON",
|
||||
"purpose": "disclosure-data-readonly",
|
||||
"mutationAllowed": false,
|
||||
"officialSources": [
|
||||
"https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS001&apiId=2019001",
|
||||
"https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS001&apiId=2019002",
|
||||
"https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS001&apiId=2019018"
|
||||
],
|
||||
"official": {
|
||||
"baseUri": "https://opendart.fss.or.kr/api/",
|
||||
"authentication": {
|
||||
"type": "query-api-key",
|
||||
"parameterName": "crtfc_key",
|
||||
"length": 40
|
||||
},
|
||||
"statusField": "status",
|
||||
"messageField": "message",
|
||||
"statusCodes": {
|
||||
"000": "success",
|
||||
"010": "unregistered-key",
|
||||
"011": "disabled-key",
|
||||
"012": "forbidden-ip",
|
||||
"013": "no-data",
|
||||
"014": "file-missing",
|
||||
"020": "request-limit-exceeded",
|
||||
"021": "company-count-exceeded",
|
||||
"100": "invalid-field",
|
||||
"101": "invalid-access",
|
||||
"800": "maintenance",
|
||||
"900": "undefined-error",
|
||||
"901": "expired-personal-data-retention"
|
||||
},
|
||||
"rateLimitNote": "020은 일반적으로 20,000건 이상의 요청에서 발생할 수 있으나 서비스별 제한이 다를 수 있음"
|
||||
},
|
||||
"kbxPolicy": {
|
||||
"credentialKey": "ExternalProviders:OpenDart:ApiKey",
|
||||
"timeoutMs": 5000,
|
||||
"maxConcurrency": 2,
|
||||
"retryStatusCodes": [
|
||||
"020",
|
||||
"800",
|
||||
"900"
|
||||
],
|
||||
"maxRetryAttempts": 1,
|
||||
"noDataStatusCodes": [
|
||||
"013"
|
||||
],
|
||||
"cacheable": true
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"id": "opendart.disclosures",
|
||||
"method": "GET",
|
||||
"path": "list.json",
|
||||
"response": "json"
|
||||
},
|
||||
{
|
||||
"id": "opendart.company",
|
||||
"method": "GET",
|
||||
"path": "company.json",
|
||||
"response": "json"
|
||||
},
|
||||
{
|
||||
"id": "opendart.corp-code",
|
||||
"method": "GET",
|
||||
"path": "corpCode.xml",
|
||||
"response": "zip-binary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "provider.kis.market-data",
|
||||
"title": "한국투자증권 KIS Open API — 국내주식 시세",
|
||||
"ownerModule": "COMMON",
|
||||
"purpose": "market-data-readonly",
|
||||
"mutationAllowed": false,
|
||||
"officialSources": [
|
||||
"https://apiportal.koreainvestment.com/apiservice-apiservice",
|
||||
"https://apiportal.koreainvestment.com/community/10000000-0000-0011-0000-000000000001/post/d0d1a83f-6f8d-4437-9700-6d26702fd989",
|
||||
"https://github.com/koreainvestment/open-trading-api/blob/main/examples_llm/domestic_stock/inquire_price/inquire_price.py",
|
||||
"https://github.com/koreainvestment/open-trading-api/blob/main/examples_llm/kis_auth.py"
|
||||
],
|
||||
"official": {
|
||||
"productionBaseUri": "https://openapi.koreainvestment.com:9443",
|
||||
"sandboxBaseUri": "https://openapivts.koreainvestment.com:29443",
|
||||
"authentication": {
|
||||
"type": "oauth2-client-credentials",
|
||||
"tokenPath": "/oauth2/tokenP",
|
||||
"bodyFields": [
|
||||
"grant_type",
|
||||
"appkey",
|
||||
"appsecret"
|
||||
],
|
||||
"grantType": "client_credentials"
|
||||
},
|
||||
"tokenValidityHours": 24,
|
||||
"tokenRenewalCycleHours": 6,
|
||||
"headers": [
|
||||
"authorization",
|
||||
"appkey",
|
||||
"appsecret",
|
||||
"tr_id",
|
||||
"custtype",
|
||||
"tr_cont"
|
||||
],
|
||||
"responseSuccess": {
|
||||
"field": "rt_cd",
|
||||
"value": "0"
|
||||
},
|
||||
"rateLimitsAsOf": "2026-04-20",
|
||||
"productionRequestsPerSecond": 18,
|
||||
"sandboxRequestsPerSecond": 1,
|
||||
"tokenRequestsPerSecond": 1,
|
||||
"concurrentSpacingRecommendationMs": [
|
||||
100,
|
||||
150
|
||||
]
|
||||
},
|
||||
"kbxPolicy": {
|
||||
"appKeyCredential": "ExternalProviders:Kis:AppKey",
|
||||
"appSecretCredential": "ExternalProviders:Kis:AppSecret",
|
||||
"environmentKey": "ExternalProviders:Kis:Environment",
|
||||
"readOnlyOnly": true,
|
||||
"tokenRefreshSkewMinutes": 5,
|
||||
"productionMinimumSpacingMs": 100,
|
||||
"sandboxMinimumSpacingMs": 1000,
|
||||
"timeoutMs": 5000,
|
||||
"maxRetryAttempts": 1,
|
||||
"retryHttpStatuses": [
|
||||
408,
|
||||
429,
|
||||
500,
|
||||
502,
|
||||
503,
|
||||
504
|
||||
],
|
||||
"cacheable": true
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"id": "kis.oauth.token",
|
||||
"method": "POST",
|
||||
"path": "/oauth2/tokenP",
|
||||
"response": "json",
|
||||
"authOperation": true
|
||||
},
|
||||
{
|
||||
"id": "kis.domestic-stock.current-price",
|
||||
"method": "GET",
|
||||
"path": "/uapi/domestic-stock/v1/quotations/inquire-price",
|
||||
"trId": "FHKST01010100",
|
||||
"response": "json",
|
||||
"query": [
|
||||
"FID_COND_MRKT_DIV_CODE",
|
||||
"FID_INPUT_ISCD"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,607 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"contractVersion": "1.1.0",
|
||||
"recipes": [
|
||||
{
|
||||
"code": "T01",
|
||||
"type": "list",
|
||||
"templateComponent": "KbxListPage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "search",
|
||||
"label": "조회",
|
||||
"group": "query",
|
||||
"shortcut": "F3",
|
||||
"permissionKind": "none"
|
||||
},
|
||||
{
|
||||
"id": "excel",
|
||||
"label": "엑셀",
|
||||
"group": "output",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"server-read-model",
|
||||
"tanstack-query",
|
||||
"search-condition-preservation",
|
||||
"server-side-bulk-selection"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"idle-before-first-search",
|
||||
"retain-grid-during-refresh",
|
||||
"retry-with-search-context",
|
||||
"partial-bulk-result"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"command-permission",
|
||||
"safe-drilldown-route",
|
||||
"masked-sensitive-cells"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.oms.order-list.bulk-ship",
|
||||
"scenario.oms.order-list.all-filtered-ship"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"search",
|
||||
"content",
|
||||
"summary"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e"
|
||||
],
|
||||
"requiredTags": [
|
||||
"bulk",
|
||||
"idempotency"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"idle-search",
|
||||
"refresh-retains-context",
|
||||
"bulk-partial-result",
|
||||
"safe-drilldown"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T02",
|
||||
"type": "master",
|
||||
"templateComponent": "KbxMasterPage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "search",
|
||||
"label": "조회",
|
||||
"group": "query",
|
||||
"shortcut": "F3",
|
||||
"permissionKind": "none"
|
||||
},
|
||||
{
|
||||
"id": "new",
|
||||
"label": "신규",
|
||||
"group": "edit",
|
||||
"permissionKind": "write"
|
||||
},
|
||||
{
|
||||
"id": "save",
|
||||
"label": "저장",
|
||||
"group": "edit",
|
||||
"shortcut": "F8",
|
||||
"variant": "primary",
|
||||
"permissionKind": "write"
|
||||
},
|
||||
{
|
||||
"id": "excel",
|
||||
"label": "엑셀",
|
||||
"group": "output",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"normalized-write-model",
|
||||
"lookup-provider",
|
||||
"server-validation",
|
||||
"optimistic-concurrency",
|
||||
"audit"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"dirty-navigation-guard",
|
||||
"conflict-reload",
|
||||
"field-validation-focus",
|
||||
"readonly-after-terminal-state"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"write-command-permission",
|
||||
"server-enforcement",
|
||||
"sensitive-value-masking"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.erp.item-master.lifecycle",
|
||||
"scenario.erp.item-master.keyboard-recovery"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"list",
|
||||
"detail"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e",
|
||||
"integration"
|
||||
],
|
||||
"requiredTags": [
|
||||
"master-crud",
|
||||
"concurrency",
|
||||
"audit"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"db-assertions"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"permission-aware-save",
|
||||
"dirty-guard",
|
||||
"conflict-reload",
|
||||
"audit-visible"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T03",
|
||||
"type": "transaction",
|
||||
"templateComponent": "KbxTransactionPage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "new",
|
||||
"label": "신규",
|
||||
"group": "edit",
|
||||
"permissionKind": "write"
|
||||
},
|
||||
{
|
||||
"id": "save",
|
||||
"label": "저장",
|
||||
"group": "edit",
|
||||
"shortcut": "F8",
|
||||
"variant": "primary",
|
||||
"permissionKind": "write"
|
||||
},
|
||||
{
|
||||
"id": "excel",
|
||||
"label": "엑셀",
|
||||
"group": "output",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"normalized-write-model",
|
||||
"header-detail-transaction",
|
||||
"server-validation",
|
||||
"optimistic-concurrency",
|
||||
"audit",
|
||||
"outbox"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"dirty-navigation-guard",
|
||||
"conflict-reload",
|
||||
"row-key-validation",
|
||||
"double-submit-guard"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"write-command-permission",
|
||||
"workflow-permission",
|
||||
"server-enforcement"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.oms.order-register.keyboard",
|
||||
"scenario.oms.order-register.conflict",
|
||||
"scenario.oms.order-register.lifecycle"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"header",
|
||||
"detail",
|
||||
"summary"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e",
|
||||
"integration"
|
||||
],
|
||||
"requiredTags": [
|
||||
"keyboard",
|
||||
"lookup",
|
||||
"conflict",
|
||||
"workflow"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"problem-json"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"f2-lookup",
|
||||
"f8-save",
|
||||
"row-key-validation",
|
||||
"conflict-recovery"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T04",
|
||||
"type": "fast-entry",
|
||||
"templateComponent": "KbxFastEntryPage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "new",
|
||||
"label": "신규",
|
||||
"group": "edit",
|
||||
"permissionKind": "write"
|
||||
},
|
||||
{
|
||||
"id": "save",
|
||||
"label": "저장",
|
||||
"group": "edit",
|
||||
"shortcut": "F8",
|
||||
"variant": "primary",
|
||||
"permissionKind": "write"
|
||||
},
|
||||
{
|
||||
"id": "excel",
|
||||
"label": "엑셀",
|
||||
"group": "output",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"typed-clipboard-normalization",
|
||||
"stable-client-row-key",
|
||||
"bulk-server-validation",
|
||||
"idempotent-bulk-save"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"error-cell-navigation",
|
||||
"paste-error-summary",
|
||||
"dirty-navigation-guard",
|
||||
"partial-save-result"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"write-command-permission",
|
||||
"lookup-entity-resolution",
|
||||
"server-enforcement"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.erp.item-price.fast-entry",
|
||||
"scenario.oms.order-register.fast-entry"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"guide",
|
||||
"content",
|
||||
"validation",
|
||||
"summary"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e"
|
||||
],
|
||||
"requiredTags": [
|
||||
"fast-entry",
|
||||
"paste",
|
||||
"fill-down",
|
||||
"idempotency"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"problem-json"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"multi-cell-paste",
|
||||
"fill-down",
|
||||
"error-navigation",
|
||||
"partial-save-result"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T05",
|
||||
"type": "master-detail",
|
||||
"templateComponent": "KbxMasterDetailPage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "search",
|
||||
"label": "조회",
|
||||
"group": "query",
|
||||
"shortcut": "F3",
|
||||
"permissionKind": "none"
|
||||
},
|
||||
{
|
||||
"id": "excel",
|
||||
"label": "엑셀",
|
||||
"group": "output",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"server-read-model",
|
||||
"master-selection-context",
|
||||
"detail-projection",
|
||||
"n-plus-one-prohibition"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"selection-restore-after-refresh",
|
||||
"retain-master-on-detail-error",
|
||||
"safe-drilldown",
|
||||
"empty-master-detail-reset"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"safe-drilldown-route",
|
||||
"masked-sensitive-detail"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.erp.inventory.master-detail-context"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"search",
|
||||
"master",
|
||||
"detail"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e"
|
||||
],
|
||||
"requiredTags": [
|
||||
"master-detail",
|
||||
"context-retention",
|
||||
"drill-down"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"api-transcript"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"master-selection-context",
|
||||
"detail-error-retains-master",
|
||||
"history-context",
|
||||
"safe-drilldown"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T06",
|
||||
"type": "queue",
|
||||
"templateComponent": "KbxQueuePage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "search",
|
||||
"label": "조회",
|
||||
"group": "query",
|
||||
"shortcut": "F3",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"exception-first-projection",
|
||||
"sla-state",
|
||||
"server-side-bulk-selection",
|
||||
"audit"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"partial-action-result",
|
||||
"retryable-vs-terminal-error",
|
||||
"stale-event-suppression",
|
||||
"detail-context-retention"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"exception-action-permission",
|
||||
"server-enforcement"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.common.operations.stale-event",
|
||||
"scenario.integration.manual-retry.idempotent",
|
||||
"scenario.common.operations.queue-recovery"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"summary",
|
||||
"exceptions",
|
||||
"content"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e",
|
||||
"integration"
|
||||
],
|
||||
"requiredTags": [
|
||||
"exception",
|
||||
"recovery",
|
||||
"context-retention"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"db-assertions"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"exception-first",
|
||||
"detail-context-retention",
|
||||
"retryable-vs-terminal",
|
||||
"partial-action-result"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T07",
|
||||
"type": "reconcile",
|
||||
"templateComponent": "KbxReconcilePage",
|
||||
"defaultCommands": [
|
||||
{
|
||||
"id": "search",
|
||||
"label": "조회",
|
||||
"group": "query",
|
||||
"shortcut": "F3",
|
||||
"permissionKind": "none"
|
||||
}
|
||||
],
|
||||
"requiredPolicies": [
|
||||
"expected-actual-difference-projection",
|
||||
"reason-code",
|
||||
"resolution-state",
|
||||
"audit"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"grace-period-before-mismatch",
|
||||
"mismatch-only-filter",
|
||||
"resolution-retry",
|
||||
"retain-comparison-context"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"resolution-permission",
|
||||
"server-enforcement"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.common.reconcile.grace-period",
|
||||
"scenario.common.reconcile.mismatch-recovery"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"search",
|
||||
"content",
|
||||
"resolution"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e",
|
||||
"integration"
|
||||
],
|
||||
"requiredTags": [
|
||||
"reconcile",
|
||||
"mismatch-filter",
|
||||
"eventual-consistency"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"db-assertions"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"mismatch-only-filter",
|
||||
"grace-period",
|
||||
"resolution-retry",
|
||||
"comparison-context"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T08",
|
||||
"type": "import",
|
||||
"templateComponent": "KbxImportPage",
|
||||
"defaultCommands": [],
|
||||
"requiredPolicies": [
|
||||
"staging-before-domain-write",
|
||||
"mapping-source-traceability",
|
||||
"background-job-threshold",
|
||||
"idempotent-commit",
|
||||
"audit"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"session-mapping-isolation",
|
||||
"validation-error-download",
|
||||
"partial-commit-result",
|
||||
"job-refresh-recovery"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"file-preflight",
|
||||
"commit-permission",
|
||||
"server-validation",
|
||||
"sensitive-column-policy"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.oms.order-import.partial"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"steps",
|
||||
"content",
|
||||
"result"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e"
|
||||
],
|
||||
"requiredTags": [
|
||||
"excel",
|
||||
"mapping",
|
||||
"staging",
|
||||
"partial-success",
|
||||
"job"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"problem-json"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"mapping-isolation",
|
||||
"validation-download",
|
||||
"commit-confirm",
|
||||
"job-refresh-recovery"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "T09",
|
||||
"type": "wms-mobile",
|
||||
"templateComponent": "KbxWmsMobilePage",
|
||||
"defaultCommands": [],
|
||||
"requiredPolicies": [
|
||||
"barcode-normalization",
|
||||
"server-validation-before-success",
|
||||
"idempotent-scan-command",
|
||||
"network-state",
|
||||
"offline-command-policy"
|
||||
],
|
||||
"recoveryPolicies": [
|
||||
"duplicate-scan-debounce",
|
||||
"response-loss-replay",
|
||||
"wrong-item-no-retry",
|
||||
"pending-command-visibility"
|
||||
],
|
||||
"securityPolicies": [
|
||||
"screen-permission",
|
||||
"execute-permission",
|
||||
"server-enforcement",
|
||||
"offline-command-allowlist"
|
||||
],
|
||||
"canonicalScenarioIds": [
|
||||
"scenario.wms.picking.idempotent-replay",
|
||||
"scenario.wms.picking.wrong-item"
|
||||
],
|
||||
"scaffoldSurfaces": [
|
||||
"context",
|
||||
"content",
|
||||
"actions"
|
||||
],
|
||||
"testProfile": {
|
||||
"requiredScenarioKinds": [
|
||||
"e2e"
|
||||
],
|
||||
"requiredTags": [
|
||||
"scanner",
|
||||
"idempotency",
|
||||
"network",
|
||||
"retry-policy"
|
||||
],
|
||||
"requiredEvidence": [
|
||||
"playwright-trace",
|
||||
"api-transcript"
|
||||
],
|
||||
"requiredChecks": [
|
||||
"scan-normalization",
|
||||
"server-before-success",
|
||||
"response-loss-replay",
|
||||
"wrong-item-no-retry"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"telemetryVersion": "1.1.0",
|
||||
"principles": {
|
||||
"purpose": "ux-improvement-and-operational-diagnosis",
|
||||
"noRawBusinessData": true,
|
||||
"noSensitiveData": true,
|
||||
"noDomClickSpying": true,
|
||||
"semanticEventsOnly": true,
|
||||
"rawRetentionDays": 90,
|
||||
"dailyAggregateRetentionMonths": 13
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"name": "screen.open",
|
||||
"category": "navigation",
|
||||
"description": "화면 진입",
|
||||
"allowedAttributes": [
|
||||
"module",
|
||||
"launchMode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "screen.close",
|
||||
"category": "navigation",
|
||||
"description": "화면 종료",
|
||||
"allowedAttributes": [
|
||||
"module",
|
||||
"closeReason"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "task.start",
|
||||
"category": "task",
|
||||
"description": "측정 가능한 업무 Task 시작",
|
||||
"allowedAttributes": [
|
||||
"taskType"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "task.complete",
|
||||
"category": "task",
|
||||
"description": "업무 Task 정상 완료",
|
||||
"allowedAttributes": [
|
||||
"taskType",
|
||||
"result"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "task.abandon",
|
||||
"category": "task",
|
||||
"description": "업무 Task 중단",
|
||||
"allowedAttributes": [
|
||||
"taskType",
|
||||
"reasonCode"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "interaction.execute",
|
||||
"category": "interaction",
|
||||
"description": "KBX 의미 단위 업무 조작 실행",
|
||||
"allowedAttributes": [
|
||||
"interactionType",
|
||||
"commandId"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search.execute",
|
||||
"category": "interaction",
|
||||
"description": "조회 실행",
|
||||
"allowedAttributes": [
|
||||
"resultBucket"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "command.execute",
|
||||
"category": "command",
|
||||
"description": "업무 Command 실행 시도",
|
||||
"allowedAttributes": [
|
||||
"commandId",
|
||||
"operationKind"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "command.succeeded",
|
||||
"category": "command",
|
||||
"description": "업무 Command 성공",
|
||||
"allowedAttributes": [
|
||||
"commandId",
|
||||
"operationKind"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "command.failed",
|
||||
"category": "command",
|
||||
"description": "업무 Command 실패",
|
||||
"allowedAttributes": [
|
||||
"commandId",
|
||||
"problemType",
|
||||
"reasonCode"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "lookup.open",
|
||||
"category": "lookup",
|
||||
"description": "Lookup 열기",
|
||||
"allowedAttributes": [
|
||||
"entityType"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "lookup.select",
|
||||
"category": "lookup",
|
||||
"description": "Lookup 선택 완료",
|
||||
"allowedAttributes": [
|
||||
"entityType",
|
||||
"selectionSource"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "grid.bulk_action",
|
||||
"category": "interaction",
|
||||
"description": "Grid 일괄처리 실행",
|
||||
"allowedAttributes": [
|
||||
"commandId",
|
||||
"countBucket"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "validation.failed",
|
||||
"category": "quality",
|
||||
"description": "저장/업무 실행 전후 검증 실패",
|
||||
"allowedAttributes": [
|
||||
"stage",
|
||||
"errorCountBucket",
|
||||
"reasonCode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "excel.import.start",
|
||||
"category": "excel",
|
||||
"description": "Excel Import 시작",
|
||||
"allowedAttributes": [
|
||||
"importType",
|
||||
"rowCountBucket"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "excel.import.completed",
|
||||
"category": "excel",
|
||||
"description": "Excel Import 완료",
|
||||
"allowedAttributes": [
|
||||
"importType",
|
||||
"result",
|
||||
"rowCountBucket"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "excel.import.failed",
|
||||
"category": "excel",
|
||||
"description": "Excel Import 실패",
|
||||
"allowedAttributes": [
|
||||
"importType",
|
||||
"reasonCode",
|
||||
"rowCountBucket"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "exception.open",
|
||||
"category": "exception",
|
||||
"description": "업무 예외 생성/노출",
|
||||
"allowedAttributes": [
|
||||
"exceptionType",
|
||||
"severity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "exception.resolved",
|
||||
"category": "exception",
|
||||
"description": "업무 예외 해결",
|
||||
"allowedAttributes": [
|
||||
"exceptionType",
|
||||
"resolutionType"
|
||||
],
|
||||
"requiresDuration": true
|
||||
},
|
||||
{
|
||||
"name": "ai.proposal.open",
|
||||
"category": "ai",
|
||||
"description": "AI 제안 확인",
|
||||
"allowedAttributes": [
|
||||
"proposalType"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ai.proposal.accept",
|
||||
"category": "ai",
|
||||
"description": "AI 제안 승인",
|
||||
"allowedAttributes": [
|
||||
"proposalType"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ai.proposal.reject",
|
||||
"category": "ai",
|
||||
"description": "AI 제안 거절",
|
||||
"allowedAttributes": [
|
||||
"proposalType",
|
||||
"reasonCode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "manual.intervention",
|
||||
"category": "outcome",
|
||||
"description": "정상 자동처리 대신 사람의 확인/수정/판단이 필요했던 업무",
|
||||
"allowedAttributes": [
|
||||
"workType",
|
||||
"reasonCode",
|
||||
"exceptionType"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "experiment.exposed",
|
||||
"category": "experiment",
|
||||
"description": "실험 Variant가 실제 화면에 렌더링되어 사용자에게 노출됨",
|
||||
"allowedAttributes": [
|
||||
"surface"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metrics": [
|
||||
{
|
||||
"key": "task_completion_time_ms",
|
||||
"label": "Task Completion Time",
|
||||
"numerator": "task.complete.duration_ms",
|
||||
"aggregation": "p50,p95",
|
||||
"unit": "ms"
|
||||
},
|
||||
{
|
||||
"key": "semantic_interactions_per_task",
|
||||
"label": "Interactions / Task",
|
||||
"numerator": "interaction.execute",
|
||||
"denominator": "task.complete",
|
||||
"aggregation": "ratio",
|
||||
"unit": "count"
|
||||
},
|
||||
{
|
||||
"key": "manual_intervention_rate",
|
||||
"label": "Manual Intervention Rate",
|
||||
"numerator": "ux_business_outcomes.manual_intervention_count",
|
||||
"denominator": "ux_business_outcomes.observed_count",
|
||||
"aggregation": "ratio",
|
||||
"unit": "percent"
|
||||
},
|
||||
{
|
||||
"key": "validation_failure_rate",
|
||||
"label": "Validation Failure Rate",
|
||||
"numerator": "validation.failed",
|
||||
"denominator": "command.execute",
|
||||
"aggregation": "ratio",
|
||||
"unit": "percent"
|
||||
},
|
||||
{
|
||||
"key": "import_failure_rate",
|
||||
"label": "Import Failure Rate",
|
||||
"numerator": "excel.import.failed",
|
||||
"denominator": "excel.import.start",
|
||||
"aggregation": "ratio",
|
||||
"unit": "percent"
|
||||
},
|
||||
{
|
||||
"key": "exception_resolution_time_ms",
|
||||
"label": "Exception Resolution Time",
|
||||
"numerator": "exception.resolved.duration_ms",
|
||||
"aggregation": "p50,p95",
|
||||
"unit": "ms"
|
||||
},
|
||||
{
|
||||
"key": "ai_proposal_acceptance_rate",
|
||||
"label": "AI Proposal Acceptance Rate",
|
||||
"numerator": "ai.proposal.accept",
|
||||
"denominator": "ai.proposal.open",
|
||||
"aggregation": "ratio",
|
||||
"unit": "percent"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "KBX Scenario Evidence",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"scenarioId",
|
||||
"runId",
|
||||
"startedAt",
|
||||
"contractVersions",
|
||||
"environment",
|
||||
"result",
|
||||
"artifacts"
|
||||
],
|
||||
"properties": {
|
||||
"scenarioId": {
|
||||
"type": "string"
|
||||
},
|
||||
"runId": {
|
||||
"type": "string"
|
||||
},
|
||||
"startedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"finishedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"result": {
|
||||
"enum": [
|
||||
"passed",
|
||||
"failed",
|
||||
"skipped"
|
||||
]
|
||||
},
|
||||
"environment": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"syntheticDataOnly"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"syntheticDataOnly": {
|
||||
"const": true
|
||||
},
|
||||
"browser": {
|
||||
"type": "string"
|
||||
},
|
||||
"database": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contractVersions": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"scenario",
|
||||
"fixture"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"correlationIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"artifacts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"sha256": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"notes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"fixtureVersion": "1.4.0",
|
||||
"syntheticOnly": true,
|
||||
"fixedReferenceClock": "2026-08-08T09:00:00Z",
|
||||
"testTenant": {
|
||||
"id": "11111111-1111-4111-8111-111111111111",
|
||||
"key": "KBX-TEST-TENANT"
|
||||
},
|
||||
"actors": [
|
||||
{
|
||||
"id": "actor.operator",
|
||||
"displayName": "테스트작업자",
|
||||
"userKey": "kbx-test-operator"
|
||||
},
|
||||
{
|
||||
"id": "actor.supervisor",
|
||||
"displayName": "테스트관리자",
|
||||
"userKey": "kbx-test-supervisor"
|
||||
}
|
||||
],
|
||||
"fixtureSets": [
|
||||
{
|
||||
"id": "fixture.oms.orders.bulk-ship",
|
||||
"description": "출고 가능 2건 + 이미 완료되어 거부될 1건",
|
||||
"refs": [
|
||||
"order.ship.ready.1",
|
||||
"order.ship.ready.2",
|
||||
"order.ship.rejected.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.oms.order-register",
|
||||
"description": "거래처/창고/품목 Lookup 입력용",
|
||||
"refs": [
|
||||
"customer.test.1",
|
||||
"warehouse.seoul",
|
||||
"item.shoe.black270"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.oms.order-conflict",
|
||||
"description": "version=7 주문 한 건",
|
||||
"refs": [
|
||||
"order.conflict.1",
|
||||
"idem.oms.order-confirm.001"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.oms.order-import",
|
||||
"description": "6행 합성 Excel Import",
|
||||
"refs": [
|
||||
"file.order-import.6rows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.wms.picking",
|
||||
"description": "A-03-02 위치 피킹 2개 필요",
|
||||
"refs": [
|
||||
"task.pick.1",
|
||||
"scan.location.a0302",
|
||||
"scan.item.shoe",
|
||||
"scan.item.wrong"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.common.operations",
|
||||
"description": "sourceVersion 10→11→10 순서 검증",
|
||||
"refs": [
|
||||
"event.stock-shortage.v10",
|
||||
"event.stock-recovered.v11"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.common.reconcile",
|
||||
"description": "OMS 10 / WMS 8 대사",
|
||||
"refs": [
|
||||
"reconcile.oms-wms.pending"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.erp.inventory-move",
|
||||
"description": "정상 이동과 동일창고 오류",
|
||||
"refs": [
|
||||
"move.valid.1",
|
||||
"move.invalid.same-warehouse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.shell.user",
|
||||
"description": "Workspace 미저장 변경 UI 전용",
|
||||
"refs": [
|
||||
"ui.order.receiver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.integration.outbox",
|
||||
"description": "외부연계 성공/일시/영구실패와 수동 재처리용 합성 메시지",
|
||||
"refs": [
|
||||
"integration.message.dispatch.1",
|
||||
"integration.message.dispatch.2",
|
||||
"integration.attempt.failed.1",
|
||||
"idem.integration.retry.001"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.integration.inbox",
|
||||
"description": "동일 Inbox 메시지 중복 수신 검증",
|
||||
"refs": [
|
||||
"integration.inbox.message.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.external-data.kis",
|
||||
"description": "KIS 현재가 fresh→expired strict 정책 검증",
|
||||
"refs": [
|
||||
"provider.kis.price.success",
|
||||
"external-data.kis.cached.expired"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.external-data.opendart",
|
||||
"description": "OPENDART 회사개황 stale-while-revalidate 검증",
|
||||
"refs": [
|
||||
"provider.opendart.company.success",
|
||||
"external-data.opendart.cached.stale"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.erp.item-price-fast-entry",
|
||||
"refs": [
|
||||
"item.shoe.black270",
|
||||
"idem.erp.item-price.001"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.erp.inventory-explorer",
|
||||
"refs": [
|
||||
"item.shoe.black270",
|
||||
"warehouse.seoul"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fixture.erp.item-master-lifecycle",
|
||||
"description": "T02 품목 수정·충돌·사용중지 Lifecycle",
|
||||
"refs": [
|
||||
"item.shoe.black270",
|
||||
"warehouse.seoul"
|
||||
]
|
||||
}
|
||||
],
|
||||
"refs": {
|
||||
"customer.test.1": {
|
||||
"kind": "customer",
|
||||
"id": "20000000-0000-4000-8000-000000000001",
|
||||
"code": "TEST-C001",
|
||||
"name": "테스트거래처A"
|
||||
},
|
||||
"warehouse.seoul": {
|
||||
"kind": "warehouse",
|
||||
"id": "30000000-0000-4000-8000-000000000001",
|
||||
"code": "TEST-WH01",
|
||||
"name": "테스트서울센터"
|
||||
},
|
||||
"warehouse.busan": {
|
||||
"kind": "warehouse",
|
||||
"id": "30000000-0000-4000-8000-000000000002",
|
||||
"code": "TEST-WH02",
|
||||
"name": "테스트부산센터"
|
||||
},
|
||||
"item.shoe.black270": {
|
||||
"kind": "item",
|
||||
"id": "40000000-0000-4000-8000-000000000001",
|
||||
"code": "TEST-ITEM-001",
|
||||
"name": "테스트운동화"
|
||||
},
|
||||
"item.wrong": {
|
||||
"kind": "item",
|
||||
"id": "40000000-0000-4000-8000-000000000002",
|
||||
"code": "TEST-ITEM-999",
|
||||
"name": "테스트오상품"
|
||||
},
|
||||
"order.ship.ready.1": {
|
||||
"kind": "order",
|
||||
"id": "50000000-0000-4000-8000-000000000001",
|
||||
"orderNo": "TEST-ORD-SHIP-001",
|
||||
"status": "READY",
|
||||
"version": 1
|
||||
},
|
||||
"order.ship.ready.2": {
|
||||
"kind": "order",
|
||||
"id": "50000000-0000-4000-8000-000000000002",
|
||||
"orderNo": "TEST-ORD-SHIP-002",
|
||||
"status": "DRAFT",
|
||||
"version": 3
|
||||
},
|
||||
"order.ship.rejected.1": {
|
||||
"kind": "order",
|
||||
"id": "50000000-0000-4000-8000-000000000003",
|
||||
"orderNo": "TEST-ORD-SHIP-003",
|
||||
"status": "SHIPPED",
|
||||
"version": 5
|
||||
},
|
||||
"order.conflict.1": {
|
||||
"kind": "order",
|
||||
"id": "50000000-0000-4000-8000-000000000004",
|
||||
"orderNo": "TEST-ORD-CONFLICT-001",
|
||||
"status": "DRAFT",
|
||||
"version": 7
|
||||
},
|
||||
"task.pick.1": {
|
||||
"kind": "picking-task",
|
||||
"id": "60000000-0000-4000-8000-000000000001",
|
||||
"taskNo": "TEST-PICK-001",
|
||||
"status": "READY",
|
||||
"version": 1
|
||||
},
|
||||
"scan.location.a0302": {
|
||||
"kind": "barcode",
|
||||
"value": "TEST-LOC-A0302",
|
||||
"classification": "synthetic"
|
||||
},
|
||||
"scan.item.shoe": {
|
||||
"kind": "barcode",
|
||||
"value": "TEST-EAN-000001",
|
||||
"classification": "synthetic"
|
||||
},
|
||||
"scan.item.wrong": {
|
||||
"kind": "barcode",
|
||||
"value": "TEST-EAN-999999",
|
||||
"classification": "synthetic"
|
||||
},
|
||||
"event.stock-shortage.v10": {
|
||||
"kind": "domain-event",
|
||||
"sourceId": "TEST-ORD-EXC-001",
|
||||
"referenceNo": "TEST-ORD-EXC-001",
|
||||
"sourceVersion": 10,
|
||||
"code": "STOCK_SHORTAGE"
|
||||
},
|
||||
"event.stock-recovered.v11": {
|
||||
"kind": "domain-event",
|
||||
"sourceId": "TEST-ORD-EXC-001",
|
||||
"referenceNo": "TEST-ORD-EXC-001",
|
||||
"sourceVersion": 11,
|
||||
"code": "STOCK_SHORTAGE"
|
||||
},
|
||||
"reconcile.oms-wms.pending": {
|
||||
"kind": "reconcile",
|
||||
"referenceNo": "TEST-ORD-REC-001",
|
||||
"expected": "10",
|
||||
"actual": "8",
|
||||
"difference": "-2"
|
||||
},
|
||||
"move.valid.1": {
|
||||
"kind": "inventory-move",
|
||||
"id": "70000000-0000-4000-8000-000000000001",
|
||||
"moveNo": "TEST-MOVE-001",
|
||||
"from": "warehouse.seoul",
|
||||
"to": "warehouse.busan"
|
||||
},
|
||||
"move.invalid.same-warehouse": {
|
||||
"kind": "inventory-move",
|
||||
"id": "70000000-0000-4000-8000-000000000002",
|
||||
"moveNo": "TEST-MOVE-ERR-001",
|
||||
"from": "warehouse.seoul",
|
||||
"to": "warehouse.seoul"
|
||||
},
|
||||
"file.order-import.6rows": {
|
||||
"kind": "xlsx-fixture",
|
||||
"path": "tests/fixtures/files/order-import-6rows.json",
|
||||
"rows": 6,
|
||||
"classification": "synthetic"
|
||||
},
|
||||
"ui.order.receiver": {
|
||||
"kind": "ui-value",
|
||||
"value": "테스트수취인"
|
||||
},
|
||||
"idem.oms.bulk-ship.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-oms-bulk-ship-001"
|
||||
},
|
||||
"idem.import.commit.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-import-commit-001"
|
||||
},
|
||||
"idem.wms.location.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-wms-location-001"
|
||||
},
|
||||
"idem.wms.item.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-wms-item-001"
|
||||
},
|
||||
"idem.wms.location.002": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-wms-location-002"
|
||||
},
|
||||
"idem.wms.wrong.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-wms-wrong-001"
|
||||
},
|
||||
"integration.message.dispatch.1": {
|
||||
"kind": "integration-message",
|
||||
"id": "81000000-0000-4000-8000-000000000001",
|
||||
"integrationId": "integration.oms.wms.dispatch",
|
||||
"aggregateId": "TEST-ORD-INT-001",
|
||||
"messageKey": "TEST-EVENT-INT-001"
|
||||
},
|
||||
"integration.message.dispatch.2": {
|
||||
"kind": "integration-message",
|
||||
"id": "81000000-0000-4000-8000-000000000002",
|
||||
"integrationId": "integration.oms.wms.dispatch",
|
||||
"aggregateId": "TEST-ORD-INT-002",
|
||||
"messageKey": "TEST-EVENT-INT-002"
|
||||
},
|
||||
"integration.inbox.message.1": {
|
||||
"kind": "integration-message",
|
||||
"id": "81000000-0000-4000-8000-000000000003",
|
||||
"integrationId": "integration.wms.oms.picking-result",
|
||||
"aggregateId": "TEST-PICK-INT-001",
|
||||
"messageKey": "TEST-EVENT-INBOX-001"
|
||||
},
|
||||
"integration.attempt.failed.1": {
|
||||
"kind": "integration-attempt",
|
||||
"id": "82000000-0000-4000-8000-000000000001",
|
||||
"integrationId": "integration.oms.wms.dispatch",
|
||||
"state": "failed"
|
||||
},
|
||||
"idem.integration.retry.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-integration-retry-001"
|
||||
},
|
||||
"provider.kis.price.success": {
|
||||
"kind": "provider-response",
|
||||
"providerId": "provider.kis.market-data",
|
||||
"datasetId": "dataset.kis.domestic-stock.current-price",
|
||||
"fixturePath": "tests/fixtures/providers/kis-current-price-success.json",
|
||||
"classification": "synthetic"
|
||||
},
|
||||
"external-data.kis.cached.expired": {
|
||||
"kind": "external-data-cache",
|
||||
"datasetId": "dataset.kis.domestic-stock.current-price",
|
||||
"cacheKey": "TEST-KIS-005930",
|
||||
"receivedAt": "2026-08-08T08:59:50Z",
|
||||
"freshUntil": "2026-08-08T08:59:53Z",
|
||||
"usableUntil": "2026-08-08T08:59:53Z"
|
||||
},
|
||||
"provider.opendart.company.success": {
|
||||
"kind": "provider-response",
|
||||
"providerId": "provider.opendart",
|
||||
"datasetId": "dataset.opendart.company-profile",
|
||||
"fixturePath": "tests/fixtures/providers/opendart-company-success.json",
|
||||
"classification": "synthetic"
|
||||
},
|
||||
"external-data.opendart.cached.stale": {
|
||||
"kind": "external-data-cache",
|
||||
"datasetId": "dataset.opendart.company-profile",
|
||||
"cacheKey": "TEST-DART-001",
|
||||
"receivedAt": "2026-08-07T08:00:00Z",
|
||||
"freshUntil": "2026-08-08T08:00:00Z",
|
||||
"usableUntil": "2026-08-15T08:00:00Z"
|
||||
},
|
||||
"idem.erp.item-price.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "kbx-test-erp-item-price-001"
|
||||
},
|
||||
"idem.oms.order-confirm.001": {
|
||||
"kind": "idempotency-key",
|
||||
"value": "KBX-TEST-ORDER-CONFIRM-001"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user