V13-FE-011: finalize search list layout slice

This commit is contained in:
2026-08-09 02:57:26 +09:00
parent 9efd202e76
commit 6422cb2b13
984 changed files with 120811 additions and 1498 deletions
@@ -0,0 +1,4 @@
{
"plainNotFoundResponses": 18,
"baseline": 18
}
@@ -0,0 +1,738 @@
{
"schemaVersion": "1.0",
"apiVersion": "2.1.0",
"sourceSha256": "8a8008b0eca039ef22b703b142dd7fa2efeaf5b14784ba9f3a954f656a1a0c8f",
"operationCount": 66,
"operations": [
{
"method": "POST",
"path": "/api/common/ai/ask",
"permission": "common.ai.use",
"id": "common.ai.ask",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/kbx/experiments/assignments",
"permission": "common.experiment.evaluate",
"id": "common.experiments.assignments",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/kbx/experiments",
"permission": "common.experiment.read",
"id": "common.experiments.overview",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/kbx/experiments/{experimentId}/rollback",
"permission": "common.experiment.manage",
"id": "common.experiments.rollback",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/kbx/experiments/{experimentId}/rollout",
"permission": "common.experiment.manage",
"id": "common.experiments.rollout",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/kbx/external-data/{datasetId}/refresh",
"permission": "common.external-data.refresh",
"id": "common.externalData.refresh",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
202
]
},
{
"method": "GET",
"path": "/api/kbx/external-data/status",
"permission": "common.external-data.read",
"id": "common.externalData.status",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/imports/sessions/{sessionId:guid}/commit",
"permission": "imports.execute",
"id": "common.imports.commit",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/imports/sessions",
"permission": "imports.execute",
"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",
"id": "common.imports.errorWorkbook",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
],
"responseType": "blob"
},
{
"method": "GET",
"path": "/api/imports/sessions/{sessionId:guid}",
"permission": "imports.execute",
"id": "common.imports.getSession",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "PUT",
"path": "/api/imports/sessions/{sessionId:guid}/mapping",
"permission": "imports.execute",
"id": "common.imports.saveMapping",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/imports/sessions/{sessionId:guid}/saved-mappings",
"permission": "imports.execute",
"id": "common.imports.saveNamedMapping",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
204
]
},
{
"method": "GET",
"path": "/api/imports/{importType}/template",
"permission": "imports.execute",
"id": "common.imports.template",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
],
"responseType": "blob"
},
{
"method": "POST",
"path": "/api/imports/sessions/{sessionId:guid}/validate",
"permission": "imports.execute",
"id": "common.imports.validate",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/integrations/attempts/{attemptId:guid}",
"permission": "common.integration.read",
"id": "common.integrations.getAttempt",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/integrations/attempts/{attemptId:guid}/retry",
"permission": "common.integration.retry",
"id": "common.integrations.retryAttempt",
"kind": "command",
"idempotency": "required",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/operations/work-items/claim",
"permission": "common.operations.claim",
"id": "common.operations.claim",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/operations/work-items/resolve",
"permission": "common.operations.resolve",
"id": "common.operations.resolve",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/operations/work-items/{id:guid}/retry",
"permission": "common.operations.retry",
"id": "common.operations.retry",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/operations/work-items",
"permission": "common.operations.read",
"id": "common.operations.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/reconcile/items/create-exceptions",
"permission": "common.operations.create",
"id": "common.reconcile.createExceptions",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/reconcile/items",
"permission": "common.reconcile.read",
"id": "common.reconcile.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/kbx/runtime/notice",
"permission": "common.runtime.read",
"id": "common.runtime.notice",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/kbx/runtime/notifications/{Id}/read",
"permission": "common.runtime.read",
"id": "common.runtime.notificationRead",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
204
]
},
{
"method": "GET",
"path": "/api/kbx/runtime/notifications",
"permission": "common.runtime.read",
"id": "common.runtime.notifications",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/kbx/runtime/operations",
"permission": "common.runtime.read",
"id": "common.runtime.operations",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/common/suggestions",
"permission": "common.suggestion.create",
"id": "common.suggestions.submit",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/kbx/ux/events",
"permission": "common.telemetry.write",
"id": "common.uxTelemetry.ingest",
"kind": "command",
"idempotency": "none",
"successStatuses": [
204
]
},
{
"method": "GET",
"path": "/api/kbx/ux/metrics",
"permission": "common.ux.read",
"id": "common.uxTelemetry.metrics",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/erp/inventory/{itemId}/history",
"permission": "erp.inventory.read",
"id": "erp.inventory.history",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/erp/inventory/{itemId}/locations",
"permission": "erp.inventory.read",
"id": "erp.inventory.locations",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/erp/inventory",
"permission": "erp.inventory.read",
"id": "erp.inventory.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/erp/item-prices/bulk",
"permission": "erp.item.price.write",
"id": "erp.itemPrices.bulkSave",
"kind": "command",
"idempotency": "required",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/erp/items/{id}",
"permission": "erp.item.read",
"id": "erp.items.get",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/erp/items",
"permission": "erp.item.read",
"id": "erp.items.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/customers/by-code/{code}",
"permission": "oms.order.read",
"id": "lookup.customers.resolveByCode",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/customers/{id}",
"permission": "oms.order.read",
"id": "lookup.customers.resolveById",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/customers",
"permission": "oms.order.read",
"id": "lookup.customers.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/items/by-code/{code}",
"permission": "erp.item.read",
"id": "lookup.items.resolveByCode",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/items/{id}",
"permission": "erp.item.read",
"id": "lookup.items.resolveById",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/items",
"permission": "erp.item.read",
"id": "lookup.items.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/warehouses/by-code/{code}",
"permission": "oms.order.read",
"id": "lookup.warehouses.resolveByCode",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/warehouses/{id}",
"permission": "oms.order.read",
"id": "lookup.warehouses.resolveById",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/lookups/warehouses",
"permission": "oms.order.read",
"id": "lookup.warehouses.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/claims/{id:guid}/approve",
"permission": "oms.claim.approve",
"id": "oms.claims.approve",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/claims/{id:guid}/complete",
"permission": "oms.claim.process",
"id": "oms.claims.complete",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/claims/{id:guid}/hold",
"permission": "oms.claim.hold",
"id": "oms.claims.hold",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/oms/claims",
"permission": "oms.claim.read",
"id": "oms.claims.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/claims/{id:guid}/start",
"permission": "oms.claim.process",
"id": "oms.claims.start",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/orders/register",
"permission": "oms.order.create",
"id": "oms.orders.register",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/oms/orders",
"permission": "oms.order.read",
"id": "oms.orders.search",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/orders/ship",
"permission": "oms.order.ship",
"id": "oms.orders.ship",
"kind": "command",
"idempotency": "required",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/wms/picking/tasks/{taskId:guid}",
"permission": "wms.picking.execute",
"id": "wms.picking.getTask",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/wms/picking/tasks/{taskId:guid}/exceptions",
"permission": "wms.picking.execute",
"id": "wms.picking.reportException",
"kind": "command",
"idempotency": "required",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/wms/picking/tasks/{taskId:guid}/scan",
"permission": "wms.picking.execute",
"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",
"id": "wms.picking.setQuantity",
"kind": "command",
"idempotency": "required",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/wms/picking/tasks/{taskId:guid}/start",
"permission": "wms.picking.execute",
"id": "wms.picking.start",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/erp/items",
"permission": "erp.item.create",
"id": "erp.items.create",
"kind": "command",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "PUT",
"path": "/api/erp/items/{id}",
"permission": "erp.item.write",
"id": "erp.items.update",
"kind": "command",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/erp/items/{id}/deactivate",
"permission": "erp.item.write",
"id": "erp.items.deactivate",
"kind": "command",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/erp/items/{id}/audit",
"permission": "erp.item.read",
"id": "erp.items.audit",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/oms/orders/{id}",
"permission": "oms.order.read",
"id": "oms.orders.get",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "POST",
"path": "/api/oms/orders/{id}/confirm",
"permission": "oms.order.confirm",
"id": "oms.orders.confirm",
"kind": "command",
"idempotency": "required",
"successStatuses": [
200
]
},
{
"method": "GET",
"path": "/api/oms/orders/{id}/audit",
"permission": "oms.order.read",
"id": "oms.orders.audit",
"kind": "query",
"idempotency": "none",
"successStatuses": [
200
]
},
{
"method": "PUT",
"path": "/api/oms/orders/{id}",
"permission": "oms.order.write",
"id": "oms.orders.update",
"kind": "command",
"idempotency": "supported",
"successStatuses": [
200
]
}
]
}
@@ -0,0 +1,599 @@
[
{
"component": "KbxInput",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxNumberField",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxMoneyField",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxQuantityField",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxDateField",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxDateRange",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxSelect",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxLookup",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxButton",
"group": "command",
"states": [
"default",
"disabled",
"loading",
"keyboard"
]
},
{
"component": "KbxCommandBar",
"group": "command",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxSearchPanel",
"group": "command",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxPageHeader",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxFormSection",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxFormGrid",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxFormSpan",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxBulkActionBar",
"group": "command",
"states": [
"default",
"disabled"
]
},
{
"component": "KbxIntegrationState",
"group": "feedback",
"states": [
"default",
"loading",
"error"
]
},
{
"component": "KbxDataProvenance",
"group": "feedback",
"states": [
"default",
"loading",
"error"
]
},
{
"component": "KbxStatus",
"group": "feedback",
"states": [
"default"
]
},
{
"component": "KbxToast",
"group": "feedback",
"states": [
"default",
"error"
]
},
{
"component": "KbxConfirm",
"group": "overlay",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxDialog",
"group": "overlay",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxDrawer",
"group": "overlay",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxDataGrid",
"group": "grid",
"states": [
"default",
"loading",
"empty",
"keyboard",
"changed",
"error"
]
},
{
"component": "KbxExcelMenu",
"group": "command",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxExcelImport",
"group": "template",
"states": [
"default",
"error",
"loading"
]
},
{
"component": "KbxJobProgress",
"group": "feedback",
"states": [
"default",
"loading",
"error"
]
},
{
"component": "KbxAuditTrail",
"group": "feedback",
"states": [
"default"
]
},
{
"component": "KbxHelpPanel",
"group": "overlay",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxAiPanel",
"group": "overlay",
"states": [
"default",
"loading"
]
},
{
"component": "KbxProposalPanel",
"group": "overlay",
"states": [
"default",
"error"
]
},
{
"component": "KbxListPage",
"group": "template",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxMasterPage",
"group": "template",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxTransactionPage",
"group": "template",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxMasterDetailPage",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxQueuePage",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxReconcilePage",
"group": "template",
"states": [
"default",
"error"
]
},
{
"component": "KbxWmsMobilePage",
"group": "wms",
"states": [
"default",
"error",
"keyboard"
]
},
{
"component": "KbxApplicationShell",
"group": "shell",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxCheckbox",
"group": "input",
"states": [
"default",
"disabled",
"readonly"
]
},
{
"component": "KbxRadio",
"group": "input",
"states": [
"default",
"disabled"
]
},
{
"component": "KbxTextarea",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxTabs",
"group": "template",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxBadge",
"group": "feedback",
"states": [
"default",
"error"
]
},
{
"component": "KbxTooltip",
"group": "feedback",
"states": [
"default",
"keyboard"
]
},
{
"component": "KbxBarcodeField",
"group": "input",
"scenarioProfile": "common-input",
"states": [
"default",
"required",
"readonly",
"disabled",
"error",
"keyboard"
]
},
{
"component": "KbxSectionHeader",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxQuickFilterBar",
"group": "command",
"states": [
"default",
"error"
]
},
{
"component": "KbxDataState",
"group": "feedback",
"states": [
"idle",
"loading",
"empty",
"error"
]
},
{
"component": "KbxTemplateStateBoundary",
"group": "feedback",
"states": [
"idle",
"ready",
"refreshing",
"error"
]
},
{
"component": "KbxSummaryBar",
"group": "feedback",
"states": [
"default"
]
},
{
"component": "KbxHomePage",
"group": "shell",
"states": [
"default",
"error",
"warning",
"keyboard"
]
},
{
"component": "KbxAccessDenied",
"group": "shell",
"states": [
"error",
"default"
]
},
{
"component": "KbxRouteNotFound",
"group": "shell",
"states": [
"error"
]
},
{
"component": "KbxTemplateContextBar",
"group": "template",
"states": [
"default",
"error"
]
},
{
"component": "KbxProgressSteps",
"group": "template",
"states": [
"default"
]
},
{
"component": "KbxLookupDialog",
"group": "overlay",
"states": [
"default",
"loading",
"empty",
"error",
"keyboard"
]
},
{
"component": "KbxValidationSummary",
"group": "feedback",
"states": [
"error",
"keyboard"
]
},
{
"component": "KbxExceptionSummary",
"group": "feedback",
"states": [
"default",
"error"
]
},
{
"component": "KbxExceptionDetailDrawer",
"group": "overlay",
"states": [
"default",
"error",
"disabled",
"keyboard"
]
},
{
"component": "KbxRecordLifecycle",
"group": "feedback",
"states": [
"default",
"changed",
"error"
]
},
{
"component": "KbxBarcodeCapture",
"group": "wms",
"states": [
"default",
"disabled",
"keyboard",
"error"
]
},
{
"component": "KbxNetworkIndicator",
"group": "wms",
"states": [
"default",
"loading",
"error"
]
},
{
"component": "KbxWmsActionButton",
"group": "wms",
"states": [
"default",
"disabled",
"loading"
]
},
{
"component": "KbxAiAssistant",
"group": "overlay",
"states": [
"default",
"loading",
"error",
"disabled"
]
},
{
"component": "KbxUtilityRail",
"group": "overlay",
"states": [
"default",
"error",
"keyboard"
]
}
]
@@ -0,0 +1,506 @@
[
{
"name": "KbxButton",
"category": "primitive",
"purpose": "표준 업무 명령 버튼",
"version": "1.0.0"
},
{
"name": "KbxTextField",
"category": "primitive",
"purpose": "표준 문자열 입력",
"version": "1.1.0"
},
{
"name": "KbxDateField",
"category": "primitive",
"purpose": "키보드 직접입력을 포함한 날짜 입력",
"version": "1.1.0"
},
{
"name": "KbxLookup",
"category": "business",
"purpose": "비동기 race/error 복구와 코드/명칭 기반 업무 엔터티 선택",
"version": "1.3.0"
},
{
"name": "KbxLookupDialog",
"category": "business",
"purpose": "Provider 오류·Empty·Pagination·Keyboard 선택을 표준화한 Lookup Dialog",
"version": "1.1.0"
},
{
"name": "KbxSearchPanel",
"category": "business",
"purpose": "조회조건의 고정 배치와 상세조건 확장",
"version": "1.3.0"
},
{
"name": "KbxCommandBar",
"category": "business",
"purpose": "Permission Host·선택·업무상태·Dirty 조건을 반영해 명령을 고정 배치",
"version": "1.3.0"
},
{
"name": "KbxDataGrid",
"category": "business",
"purpose": "조회·편집·대량처리용 업무 Grid",
"version": "1.4.0"
},
{
"name": "KbxFormSection",
"category": "business",
"purpose": "Token 기반 Section heading·description·action 영역을 제공하는 Master/Transaction 입력 Section",
"version": "1.1.0"
},
{
"name": "KbxFormGrid",
"category": "business",
"purpose": "Desktop 2-column·좁은 화면 1-column 전환을 표준화하는 Form layout",
"version": "1.0.0"
},
{
"name": "KbxFormSpan",
"category": "business",
"purpose": "주소·비고 등 관계상 넓게 보여야 하는 Field의 명시적 full-span layout",
"version": "1.0.0"
},
{
"name": "KbxValidationSummary",
"category": "business",
"purpose": "저장 실패 입력 오류의 요약 및 이동",
"version": "1.0.1"
},
{
"name": "KbxStatus",
"category": "business",
"purpose": "Domain 상태를 일관된 semantic 상태로 표시",
"version": "1.0.0"
},
{
"name": "KbxHelpPanel",
"category": "business",
"purpose": "화면 목적·사용순서·단축키·주의사항 도움말",
"version": "1.0.0"
},
{
"name": "KbxListPage",
"category": "template",
"purpose": "조회 전·조회·재조회·Empty/Error 복구와 Search·Quick Filter·Grid·Summary를 고정한 조회형 표준 화면",
"version": "1.6.0"
},
{
"name": "KbxTransactionPage",
"category": "template",
"purpose": "Header/Detail·Context·Lifecycle·Summary를 결합한 거래형 표준 화면",
"version": "1.6.0"
},
{
"name": "KbxMasterPage",
"category": "template",
"purpose": "조회 전 상태·목록/상세·Tabs·Context·Dirty/Conflict/Audit Lifecycle을 결합한 기준정보 표준 화면",
"version": "1.6.0"
},
{
"name": "KbxMasterDetailPage",
"category": "template",
"purpose": "조회 전·재조회 Context를 보존하며 Master·Detail·이력·Drawer를 함께 탐색하는 표준 화면",
"version": "1.6.0"
},
{
"name": "KbxWmsMobilePage",
"category": "wms",
"purpose": "Template/Permission/Network 경계를 포함한 PDA·Scanner 현장 작업 Shell",
"version": "1.5.0"
},
{
"name": "KbxBarcodeCapture",
"category": "wms",
"purpose": "Keyboard-wedge/Camera/수동 입력과 bounded buffer·짧은 중복 debounce를 표준화",
"version": "1.1.0"
},
{
"name": "KbxNetworkIndicator",
"category": "wms",
"purpose": "현장 네트워크 및 대기 Command 상태 표시",
"version": "1.0.0"
},
{
"name": "KbxWmsActionButton",
"category": "wms",
"purpose": "장갑/터치 환경용 주요 업무 CTA",
"version": "1.1.0"
},
{
"name": "KbxExcelMenu",
"category": "business",
"purpose": "업무 화면의 Excel 다운로드·업로드 진입점",
"version": "1.0.0"
},
{
"name": "KbxExcelImport",
"category": "business",
"purpose": "파일 preflight·1:1 매핑·검증·반영 확인·부분실패 복구를 포함한 Excel Import 흐름",
"version": "1.1.0"
},
{
"name": "KbxJobProgress",
"category": "business",
"purpose": "Hangfire 장시간 작업 진행상태 표시",
"version": "1.0.0"
},
{
"name": "KbxImportPage",
"category": "template",
"purpose": "Progress·Context·Import Content·Result를 고정한 Excel Import 표준 화면",
"version": "1.4.0"
},
{
"name": "KbxExceptionCenter",
"category": "business",
"purpose": "예외 요약·목록·상세·안전한 후속 Action을 결합한 운영 컴포넌트",
"version": "1.0.0"
},
{
"name": "KbxExceptionSummary",
"category": "business",
"purpose": "업무 예외 유형별 건수와 빠른 필터",
"version": "1.0.1"
},
{
"name": "KbxExceptionDetailDrawer",
"category": "business",
"purpose": "표준 Drawer·Permission Host로 예외 원인·대상·후속 Action을 안전하게 처리",
"version": "1.1.0"
},
{
"name": "KbxWorkQueuePage",
"category": "template",
"purpose": "사용자가 지금 처리해야 할 업무와 예외를 우선하는 Queue 호환 화면",
"version": "1.4.0"
},
{
"name": "KbxReconcilePage",
"category": "template",
"purpose": "조회 전·재조회·Expected/Actual/Difference·Resolution·Audit 기반 정합성 대사 화면",
"version": "1.5.0"
},
{
"name": "KbxUtilityRail",
"category": "business",
"purpose": "도움말·AI 오류복구·사용자 제안을 동일한 우측 보조영역에 통합",
"version": "1.2.0"
},
{
"name": "KbxAiAssistant",
"category": "business",
"purpose": "Capability/Permission guard와 오류 재질문을 포함한 현재 화면 기반 AI 보조",
"version": "1.1.0"
},
{
"name": "KbxUserSuggestionPanel",
"category": "business",
"purpose": "현재 화면 맥락을 포함한 저마찰 사용자 개선 제안",
"version": "1.0.0"
},
{
"name": "KbxRuntimeBanner",
"category": "business",
"purpose": "장애·읽기전용·오프라인 등 현재 운영모드를 화면 상단에 명확히 표시",
"version": "1.0.0"
},
{
"name": "KbxFreshnessIndicator",
"category": "business",
"purpose": "조회 데이터의 관측시각과 stale 여부를 표시하고 재조회를 제공",
"version": "1.0.0"
},
{
"name": "KbxConflictResolver",
"category": "business",
"purpose": "낙관적 동시성 충돌 시 내 화면과 최신 값을 비교하고 안전하게 다시 읽기",
"version": "1.0.0"
},
{
"name": "KbxOperationCenter",
"category": "business",
"purpose": "Excel·대량처리·연계 등 장시간 작업의 진행률과 결과를 지속적으로 표시",
"version": "1.0.0"
},
{
"name": "KbxNotificationCenter",
"category": "business",
"purpose": "사용자가 확인해야 할 완료·부분실패·운영 알림을 비차단 방식으로 제공",
"version": "1.0.0"
},
{
"name": "KbxRecordLifecycle",
"category": "business",
"purpose": "Version·Workflow·Conflict·Audit를 하나의 재사용 가능한 레코드 생명주기 영역으로 통합",
"version": "1.0.0"
},
{
"name": "KbxWorkflowBar",
"category": "business",
"purpose": "Permission Host를 반영해 현재 업무상태·표준 상태흐름·허용 전이를 한 위치에서 표현",
"version": "1.1.0"
},
{
"name": "KbxGlobalHeader",
"category": "shell",
"purpose": "제품·실제 Module Selector·메뉴검색·운영알림·사용자 Action을 고정 배치하는 전역 Header",
"version": "1.3.0"
},
{
"name": "KbxSideNavigation",
"category": "shell",
"purpose": "Header와 동기화된 모듈 전환·검색·즐겨찾기·최근메뉴·2단계 업무메뉴 탐색",
"version": "1.3.0"
},
{
"name": "KbxWorkspaceTabs",
"category": "shell",
"purpose": "키보드 이동·Dirty·Pin·Overflow를 가진 다중 업무 Workspace Tab",
"version": "1.2.0"
},
{
"name": "KbxMenuSearch",
"category": "shell",
"purpose": "즐겨찾기·최근업무 우선순위와 메뉴명·화면코드·업무 키워드를 결합하고 Focus를 복원하는 메뉴검색",
"version": "1.3.0"
},
{
"name": "KbxApplicationShell",
"category": "shell",
"purpose": "Global Header·Module Navigation·Workspace Tabs·Skip Navigation·업무영역과 사용자 Action 전달을 통합하는 Application Shell",
"version": "1.5.0"
},
{
"name": "KbxUnsavedChangesDialog",
"category": "shell",
"purpose": "Workspace 이동·종료 시 미저장 변경의 유지·폐기·저장후이동을 표준화",
"version": "1.0.0"
},
{
"name": "KbxInput",
"category": "primitive",
"purpose": "표준 문자열 입력의 canonical API",
"version": "1.2.0"
},
{
"name": "KbxNumberField",
"category": "primitive",
"purpose": "숫자 입력·표시 형식을 분리한 공통 숫자 입력",
"version": "1.1.0"
},
{
"name": "KbxMoneyField",
"category": "business",
"purpose": "통화·정밀도·음수정책을 포함한 금액 입력",
"version": "1.1.0"
},
{
"name": "KbxQuantityField",
"category": "business",
"purpose": "단위·가용수량을 포함한 업무 수량 입력",
"version": "1.1.0"
},
{
"name": "KbxDateRange",
"category": "business",
"purpose": "ERP 조회용 시작일·종료일 범위 입력",
"version": "1.1.0"
},
{
"name": "KbxSelect",
"category": "primitive",
"purpose": "짧고 고정된 Enum 선택",
"version": "1.1.0"
},
{
"name": "KbxPageHeader",
"category": "business",
"purpose": "화면명·경로·Utility 진입점의 고정 배치",
"version": "1.1.0"
},
{
"name": "KbxBulkActionBar",
"category": "business",
"purpose": "Permission Host와 선택 건수를 반영한 대량 업무 Action의 공통 표현",
"version": "1.1.0"
},
{
"name": "KbxDialog",
"category": "primitive",
"purpose": "위험확정·짧은 Lookup·사유입력용 제한적 Modal",
"version": "1.0.0"
},
{
"name": "KbxDrawer",
"category": "primitive",
"purpose": "조회맥락을 유지하는 상세·Audit·Help 보조영역",
"version": "1.0.0"
},
{
"name": "KbxToast",
"category": "business",
"purpose": "시간이 지나도 해결이 필요하지 않은 성공·정보 Feedback",
"version": "1.0.0"
},
{
"name": "KbxConfirm",
"category": "business",
"purpose": "위험 수준과 업무 결과를 설명하는 확인 UX",
"version": "1.0.0"
},
{
"name": "KbxAuditTrail",
"category": "business",
"purpose": "사용자 관점의 변경 전·후·행위자·사유 이력 표시",
"version": "1.0.0"
},
{
"name": "KbxProposalPanel",
"category": "business",
"purpose": "Permission·Server validation 상태를 확인한 뒤 AI 변경안을 승인하는 공통 패턴",
"version": "1.1.0"
},
{
"name": "KbxAiPanel",
"category": "business",
"purpose": "KbxAiAssistant 오류·화면명 계약을 포함하는 표준 명칭 호환 API",
"version": "1.1.0"
},
{
"name": "KbxFastEntryPage",
"category": "template",
"purpose": "Enter·Paste·Fill Down·Context 중심 대량 행 입력 화면",
"version": "1.7.0"
},
{
"name": "KbxQueuePage",
"category": "template",
"purpose": "조회 전·예외 우선 Work Summary·Context·Queue·Quick Action 표준 Template",
"version": "1.6.0"
},
{
"name": "KbxMaskedValue",
"category": "business",
"purpose": "민감정보의 기본 마스킹·권한 기반 전체보기 진입점을 표준화",
"version": "1.0.0"
},
{
"name": "KbxIntegrationState",
"category": "business",
"purpose": "Business State와 분리된 외부연계 대기·재시도·완료·실패 상태를 사용자에게 설명",
"version": "1.0.0"
},
{
"name": "KbxDataProvenance",
"category": "business",
"purpose": "외부 데이터의 출처·기준시각·수신시각·정규화 버전·stale 상태를 재현 가능하게 표시",
"version": "1.0.0"
},
{
"name": "KbxCheckbox",
"category": "primitive",
"purpose": "Boolean 업무값의 키보드·마우스 선택",
"version": "1.1.0"
},
{
"name": "KbxRadio",
"category": "primitive",
"purpose": "소수의 상호배타 선택지 입력",
"version": "1.1.0"
},
{
"name": "KbxTextarea",
"category": "primitive",
"purpose": "메모·사유 등 다중행 문자열 입력",
"version": "1.1.0"
},
{
"name": "KbxTabs",
"category": "primitive",
"purpose": "상세정보를 동일 화면 맥락에서 분리하는 표준 Tabs",
"version": "1.1.0"
},
{
"name": "KbxBadge",
"category": "primitive",
"purpose": "보조 상태·건수의 짧은 텍스트 표시",
"version": "1.0.0"
},
{
"name": "KbxTooltip",
"category": "primitive",
"purpose": "짧은 Field·Action 도움말을 Hover와 Focus 모두에서 표시",
"version": "1.0.0"
},
{
"name": "KbxBarcodeField",
"category": "business",
"purpose": "Desktop 업무 Form의 바코드 문자열 입력과 정규화",
"version": "1.1.0"
},
{
"name": "KbxSectionHeader",
"category": "business",
"purpose": "Form·Detail Grid Section의 제목·건수·보조 Action 위치 표준화",
"version": "1.0.0"
},
{
"name": "KbxQuickFilterBar",
"category": "business",
"purpose": "현재 조회결과 KPI를 즉시 필터로 전환하는 Actionable Summary",
"version": "1.0.0"
},
{
"name": "KbxDataState",
"category": "business",
"purpose": "Idle·Loading·Empty·Error 상태와 복구 Action을 공통 표현",
"version": "1.1.0"
},
{
"name": "KbxTemplateStateBoundary",
"category": "business",
"purpose": "표준 Template의 Idle·Loading·Empty·Error·Refreshing 상태와 조회 복구 Action을 Context 손실 없이 통합",
"version": "1.1.0"
},
{
"name": "KbxSummaryBar",
"category": "business",
"purpose": "조회건수·선택건수·수량·금액 등 화면 하단 요약의 고정 표현",
"version": "1.0.0"
},
{
"name": "KbxHomePage",
"category": "shell",
"purpose": "미저장·실패 작업·중요 알림을 우선하고 같은 우선순위는 최신 발생 순으로 정렬하며 overflow 전체 건수까지 정확히 제공하는 안전한 Home Workbench",
"version": "1.7.0"
},
{
"name": "KbxAccessDenied",
"category": "shell",
"purpose": "직접 URL 접근을 포함한 Frontend 권한 거부 상태와 화면 정보 비노출 secure-default 복구",
"version": "1.2.0"
},
{
"name": "KbxRouteNotFound",
"category": "shell",
"purpose": "등록되지 않은 딥링크를 안전한 메뉴검색/Home 흐름으로 복구",
"version": "1.0.0"
},
{
"name": "KbxTemplateContextBar",
"category": "template",
"purpose": "T01~T08의 조회건수·선택·오류·기준시각 등 업무 문맥을 동일 위치에 표현",
"version": "1.0.0"
},
{
"name": "KbxProgressSteps",
"category": "business",
"purpose": "Import 등 단계형 업무의 현재/완료 단계를 접근성 있게 표현",
"version": "1.0.0"
}
]
@@ -0,0 +1,528 @@
{
"schemaVersion": "1.0",
"contractVersion": "1.0.0",
"sourceSha256": "e09186d626b034a524b7cdf78f1e4bb6adbc112975b3baf4fd6194b1c1abd771",
"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"
],
"settingCount": 33,
"environmentCount": 4,
"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,106 @@
{
"generatedFrom": "packages/kbx-ui/src",
"policy": "ratchet-only: existing hardcoded literals may decrease but must not increase; new files start at zero",
"totals": {
"hex": 2,
"px": 129,
"total": 131
},
"files": {
"packages/kbx-ui/src/components/KbxAuditTrail.vue": {
"hex": 0,
"px": 6,
"total": 6
},
"packages/kbx-ui/src/components/KbxBulkActionBar.vue": {
"hex": 0,
"px": 3,
"total": 3
},
"packages/kbx-ui/src/components/KbxConflictResolver.vue": {
"hex": 0,
"px": 13,
"total": 13
},
"packages/kbx-ui/src/components/KbxDialog.vue": {
"hex": 0,
"px": 3,
"total": 3
},
"packages/kbx-ui/src/components/KbxDrawer.vue": {
"hex": 0,
"px": 1,
"total": 1
},
"packages/kbx-ui/src/components/KbxExcelMenu.vue": {
"hex": 0,
"px": 9,
"total": 9
},
"packages/kbx-ui/src/components/KbxExceptionCenter.vue": {
"hex": 0,
"px": 1,
"total": 1
},
"packages/kbx-ui/src/components/KbxFreshnessIndicator.vue": {
"hex": 0,
"px": 1,
"total": 1
},
"packages/kbx-ui/src/components/KbxHelpPanel.vue": {
"hex": 0,
"px": 12,
"total": 12
},
"packages/kbx-ui/src/components/KbxJobProgress.vue": {
"hex": 0,
"px": 7,
"total": 7
},
"packages/kbx-ui/src/components/KbxLookupDialog.vue": {
"hex": 0,
"px": 2,
"total": 2
},
"packages/kbx-ui/src/components/KbxNotificationCenter.vue": {
"hex": 0,
"px": 10,
"total": 10
},
"packages/kbx-ui/src/components/KbxOperationCenter.vue": {
"hex": 0,
"px": 9,
"total": 9
},
"packages/kbx-ui/src/components/KbxRuntimeBanner.vue": {
"hex": 0,
"px": 6,
"total": 6
},
"packages/kbx-ui/src/components/KbxStatus.vue": {
"hex": 0,
"px": 8,
"total": 8
},
"packages/kbx-ui/src/components/KbxToast.vue": {
"hex": 0,
"px": 7,
"total": 7
},
"packages/kbx-ui/src/components/KbxUserSuggestionPanel.vue": {
"hex": 0,
"px": 15,
"total": 15
},
"packages/kbx-ui/src/shell/KbxUnsavedChangesDialog.vue": {
"hex": 0,
"px": 12,
"total": 12
},
"packages/kbx-ui/src/wms/KbxNetworkIndicator.vue": {
"hex": 2,
"px": 4,
"total": 6
}
}
}
@@ -0,0 +1,88 @@
{
"schemaVersion": "1.0",
"experimentVersion": "1.0.0",
"sourceSha256": "2510a2927bab297858e09e75c8af9bb766d91b92cc0daf99433f6377d399fbf9",
"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,130 @@
{
"schemaVersion": "1.0",
"contractVersion": "1.0.0",
"sourceSha256": "da54ff739c6dc5ed6f9390d1fc8a8e138060d7cf19531a80cc91e421d62954a4",
"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,125 @@
{
"dictionaryVersion": "1.1.0",
"canonicalFieldCount": 51,
"scannedFiles": 103,
"fieldOccurrences": 146,
"uniqueFieldKeysObserved": 90,
"canonicalKeysUsed": [
"address1",
"address2",
"allocatedQty",
"amount",
"availableQty",
"channelName",
"customerCode",
"customerName",
"effectiveDate",
"exceptionCount",
"holdQty",
"itemCode",
"itemName",
"itemSummary",
"locationCode",
"lotNo",
"occurredAt",
"onHandQty",
"orderDate",
"orderNo",
"orderQty",
"orderedAt",
"ownerName",
"phone",
"postalCode",
"quantity",
"receiverName",
"referenceNo",
"remark",
"specification",
"status",
"totalQty",
"unitPrice",
"updatedAt",
"warehouseCode",
"warehouseId",
"warehouseName"
],
"localOrUnknownKeys": [
"active",
"actor",
"actualValue",
"ageMinutes",
"allocationStatus",
"balanceQty",
"businessType",
"cacheEntries",
"claimNo",
"code",
"completedLines",
"datasetId",
"decision",
"detail",
"differenceValue",
"dueDate",
"expectedValue",
"experimentId",
"inboundQty",
"label",
"lastReceivedAt",
"moveQty",
"name",
"oldestFreshUntil",
"outboundQty",
"p50",
"p95",
"progress",
"qty",
"reason",
"reasonText",
"requestedAt",
"requestedQty",
"rolloutPercent",
"sampleCount",
"screenId",
"severity",
"shipmentStatus",
"slaAt",
"sourceLabel",
"sourceModule",
"staleEntries",
"state",
"targetLabel",
"taskNo",
"taskType",
"title",
"totalLines",
"type",
"unavailableEntries",
"unit",
"value",
"waveNo"
],
"promotionCandidates": [
{
"key": "code",
"occurrences": 2
},
{
"key": "name",
"occurrences": 2
},
{
"key": "sourceLabel",
"occurrences": 2
},
{
"key": "state",
"occurrences": 2
},
{
"key": "unit",
"occurrences": 2
}
],
"deprecatedUses": [],
"note": "Unknown keys are not automatically errors: local read-model fields may remain local. Repeated business concepts are promotion candidates for the canonical dictionary."
}
@@ -0,0 +1,709 @@
{
"version": "1.1.0",
"source": "contracts/fields/kbx.fields.json",
"sourceSha256": "f76e073cd8052e9fddb25cc73322686c889822a22fab712ff1a25bef29b32e3c",
"count": 51,
"fields": [
{
"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": "allocatedQty",
"label": "할당수량",
"aliases": [
"AllocatedQty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "amount",
"label": "금액",
"aliases": [
"Amount",
"주문금액"
],
"dataType": "money",
"precision": 18,
"scale": 2,
"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": "barcode",
"label": "바코드",
"aliases": [
"Barcode",
"EAN",
"JAN"
],
"dataType": "code",
"maxLength": 100,
"lookupEntity": "item",
"importable": true,
"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": "createdAt",
"label": "등록일시",
"aliases": [
"CreatedAt"
],
"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": "customerCode",
"label": "거래처코드",
"aliases": [
"거래처",
"업체코드",
"CustomerCode"
],
"dataType": "code",
"required": true,
"maxLength": 50,
"lookupEntity": "customer",
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "customerId",
"label": "거래처ID",
"aliases": [
"CustomerId"
],
"dataType": "lookup",
"lookupEntity": "customer",
"readonly": true,
"importable": false,
"exportable": false,
"sensitive": false
},
{
"key": "customerName",
"label": "거래처명",
"aliases": [
"CustomerName",
"업체명"
],
"dataType": "text",
"maxLength": 200,
"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": "exceptionCount",
"label": "예외건수",
"aliases": [
"ExceptionCount",
"오류건수"
],
"dataType": "integer",
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "expiryDate",
"label": "유통기한",
"aliases": [
"ExpiryDate",
"ExpirationDate"
],
"dataType": "date",
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "holdQty",
"label": "보류수량",
"aliases": [
"HoldQty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "itemCode",
"label": "품목코드",
"aliases": [
"상품코드",
"SKU",
"ItemCode"
],
"dataType": "code",
"required": true,
"maxLength": 80,
"lookupEntity": "item",
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "itemId",
"label": "품목ID",
"aliases": [
"ItemId"
],
"dataType": "lookup",
"lookupEntity": "item",
"readonly": true,
"importable": false,
"exportable": false,
"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": "locationCode",
"label": "로케이션",
"aliases": [
"Location",
"LocationCode",
"위치"
],
"dataType": "code",
"maxLength": 80,
"lookupEntity": "location",
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "locationId",
"label": "로케이션ID",
"aliases": [
"LocationId"
],
"dataType": "lookup",
"lookupEntity": "location",
"readonly": true,
"importable": false,
"exportable": false,
"sensitive": false
},
{
"key": "lotNo",
"label": "LOT",
"aliases": [
"LotNo",
"LOT번호"
],
"dataType": "code",
"maxLength": 100,
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "occurredAt",
"label": "발생시각",
"aliases": [
"OccurredAt"
],
"dataType": "datetime",
"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": "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": "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": "orderQty",
"label": "주문수량",
"aliases": [
"주문수량",
"수량",
"Qty",
"OrderQty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"importable": true,
"exportable": true,
"sensitive": false,
"required": true
},
{
"key": "ownerName",
"label": "담당자",
"aliases": [
"OwnerName",
"담당"
],
"dataType": "text",
"maxLength": 100,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "phone",
"label": "연락처",
"aliases": [
"휴대폰",
"전화번호",
"Phone"
],
"dataType": "text",
"required": true,
"maxLength": 50,
"importable": true,
"exportable": true,
"sensitive": true,
"masking": "phone"
},
{
"key": "pickedQty",
"label": "피킹수량",
"aliases": [
"PickedQty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "postalCode",
"label": "우편번호",
"aliases": [
"ZipCode",
"PostalCode"
],
"dataType": "text",
"maxLength": 20,
"importable": true,
"exportable": true,
"sensitive": true,
"masking": "address"
},
{
"key": "quantity",
"label": "수량",
"aliases": [
"Qty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"importable": false,
"exportable": false,
"sensitive": false
},
{
"key": "receiverName",
"label": "수취인",
"aliases": [
"받는분",
"수령인",
"ReceiverName"
],
"dataType": "text",
"required": true,
"maxLength": 100,
"importable": true,
"exportable": true,
"sensitive": true,
"masking": "name"
},
{
"key": "referenceNo",
"label": "참조번호",
"aliases": [
"ReferenceNo"
],
"dataType": "code",
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "remark",
"label": "비고",
"aliases": [
"메모",
"배송메모",
"Remark"
],
"dataType": "text",
"maxLength": 500,
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "shippedQty",
"label": "출고수량",
"aliases": [
"ShippedQty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "specification",
"label": "규격",
"aliases": [
"Specification",
"Spec"
],
"dataType": "text",
"maxLength": 200,
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "status",
"label": "상태",
"aliases": [
"Status"
],
"dataType": "status",
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "totalQty",
"label": "총수량",
"aliases": [
"TotalQty"
],
"dataType": "quantity",
"precision": 18,
"scale": 4,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "unitPrice",
"label": "단가",
"aliases": [
"판매단가",
"UnitPrice"
],
"dataType": "money",
"precision": 18,
"scale": 4,
"importable": true,
"exportable": true,
"sensitive": false
},
{
"key": "updatedAt",
"label": "수정일시",
"aliases": [
"UpdatedAt"
],
"dataType": "datetime",
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
},
{
"key": "updatedBy",
"label": "수정자",
"aliases": [
"UpdatedBy"
],
"dataType": "text",
"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": "warehouseCode",
"label": "창고코드",
"aliases": [
"창고",
"창고코드",
"출고창고",
"WarehouseCode"
],
"dataType": "code",
"required": true,
"maxLength": 50,
"lookupEntity": "warehouse",
"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": "warehouseName",
"label": "창고명",
"aliases": [
"WarehouseName"
],
"dataType": "text",
"maxLength": 200,
"readonly": true,
"importable": false,
"exportable": true,
"sensitive": false
}
]
}
@@ -0,0 +1,194 @@
{
"schemaVersion": "1.0",
"integrationVersion": "1.0.0",
"sourceSha256": "607853e43ab35fdacc1adea7d5b470dfad791f6718afba215b5600c974b0642e",
"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,98 @@
[
{
"screenId": "OMS-ORD-001",
"path": "/oms/orders",
"section": "주문",
"order": 10
},
{
"screenId": "OMS-ORD-002",
"path": "/oms/orders/new",
"section": "주문",
"order": 20
},
{
"screenId": "OMS-ORD-003",
"path": "/oms/orders/import",
"section": "주문",
"order": 30
},
{
"screenId": "OMS-CLM-001",
"path": "/oms/claims",
"section": "CS/클레임",
"order": 40
},
{
"screenId": "ERP-MST-ITEM-001",
"path": "/erp/items",
"section": "기준정보",
"order": 10
},
{
"screenId": "ERP-PRICE-001",
"path": "/erp/item-prices",
"section": "기준정보",
"order": 15
},
{
"screenId": "ERP-PUR-001",
"path": "/erp/purchases/new",
"section": "구매",
"order": 20
},
{
"screenId": "ERP-INV-001",
"path": "/erp/inventory",
"section": "재고",
"order": 30
},
{
"screenId": "ERP-INV-MOVE-001",
"path": "/erp/inventory-moves/new",
"section": "재고",
"order": 40
},
{
"screenId": "WMS-WORK-001",
"path": "/wms/work",
"section": "작업관리",
"order": 10
},
{
"screenId": "COMMON-OPS-001",
"path": "/operations/exceptions",
"section": "운영",
"order": 10
},
{
"screenId": "COMMON-REC-001",
"path": "/operations/reconcile",
"section": "운영",
"order": 20
},
{
"screenId": "COMMON-EXP-001",
"path": "/internal/kbx/experiments",
"section": "KBX",
"order": 75
},
{
"screenId": "COMMON-UX-001",
"path": "/internal/kbx/ux-metrics",
"section": "KBX",
"order": 80
},
{
"screenId": "COMMON-DATA-001",
"path": "/internal/kbx/external-data",
"section": "KBX",
"order": 85
},
{
"screenId": "COMMON-DS-001",
"path": "/internal/kbx/catalog",
"section": "KBX",
"order": 90
}
]
@@ -0,0 +1,546 @@
{
"schemaVersion": "1.0",
"permissionVersion": "1.8.0",
"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
}
]
}
@@ -0,0 +1,13 @@
{
"schemaVersion": "1.0",
"sourceSha256": "5c06fd380f07e56e7e0188cce405dfaf2c1a2361a2d3526237c96e8a6802cd42",
"types": [
"validation",
"business-rule",
"conflict",
"permission",
"not-found",
"integration",
"system"
]
}
@@ -0,0 +1,225 @@
{
"schemaVersion": "1.0",
"providerVersion": "1.0.0",
"sourceSha256": "5515e5e002767ed895ea0442003829b0bad8fa9c7a0693ce6cdcbd65969b830f",
"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": {
"100": "invalid-field",
"101": "invalid-access",
"800": "maintenance",
"900": "undefined-error",
"901": "expired-personal-data-retention",
"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"
},
"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"
]
}
]
}
]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,290 @@
# KBX Release Impact
- Baseline: v21
- Contract version: 1.22.0
- Declared level: major
- Required level: major
- Compatible: YES
## Tracked contract changes
- **minor** component added: `KbxFormGrid`
- **minor** component added: `KbxFormSpan`
- **minor** component added: `KbxRecordLifecycle`
- **minor** component added: `KbxCheckbox`
- **minor** component added: `KbxRadio`
- **minor** component added: `KbxTextarea`
- **minor** component added: `KbxTabs`
- **minor** component added: `KbxBadge`
- **minor** component added: `KbxTooltip`
- **minor** component added: `KbxBarcodeField`
- **minor** component added: `KbxSectionHeader`
- **minor** component added: `KbxQuickFilterBar`
- **minor** component added: `KbxDataState`
- **minor** component added: `KbxTemplateStateBoundary`
- **minor** component added: `KbxSummaryBar`
- **minor** component added: `KbxHomePage`
- **minor** component added: `KbxAccessDenied`
- **minor** component added: `KbxRouteNotFound`
- **minor** component added: `KbxTemplateContextBar`
- **minor** component added: `KbxProgressSteps`
- **minor** component version: `KbxTextField` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxDateField` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxLookup` ("1.0.0" → "1.3.0")
- **minor** component version: `KbxLookupDialog` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxSearchPanel` ("1.0.0" → "1.3.0")
- **minor** component version: `KbxCommandBar` ("1.0.0" → "1.3.0")
- **minor** component version: `KbxDataGrid` ("1.0.0" → "1.4.0")
- **minor** component version: `KbxFormSection` ("1.0.0" → "1.1.0")
- **patch** component version: `KbxValidationSummary` ("1.0.0" → "1.0.1")
- **minor** component version: `KbxListPage` ("1.0.0" → "1.6.0")
- **minor** component version: `KbxTransactionPage` ("1.0.0" → "1.6.0")
- **minor** component version: `KbxMasterPage` ("1.0.0" → "1.6.0")
- **minor** component version: `KbxMasterDetailPage` ("1.0.0" → "1.6.0")
- **minor** component version: `KbxWmsMobilePage` ("1.0.0" → "1.5.0")
- **minor** component version: `KbxBarcodeCapture` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxWmsActionButton` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxExcelImport` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxImportPage` ("1.0.0" → "1.4.0")
- **patch** component version: `KbxExceptionSummary` ("1.0.0" → "1.0.1")
- **minor** component version: `KbxExceptionDetailDrawer` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxWorkQueuePage` ("1.0.0" → "1.4.0")
- **minor** component version: `KbxReconcilePage` ("1.0.0" → "1.5.0")
- **minor** component version: `KbxUtilityRail` ("1.0.0" → "1.2.0")
- **minor** component version: `KbxAiAssistant` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxWorkflowBar` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxGlobalHeader` ("1.0.0" → "1.3.0")
- **minor** component version: `KbxSideNavigation` ("1.0.0" → "1.3.0")
- **minor** component version: `KbxWorkspaceTabs` ("1.0.0" → "1.2.0")
- **minor** component version: `KbxMenuSearch` ("1.0.0" → "1.3.0")
- **minor** component version: `KbxApplicationShell` ("1.0.0" → "1.5.0")
- **minor** component version: `KbxInput` ("1.1.0" → "1.2.0")
- **minor** component version: `KbxNumberField` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxMoneyField` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxQuantityField` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxDateRange` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxSelect` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxPageHeader` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxBulkActionBar` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxProposalPanel` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxAiPanel` ("1.0.0" → "1.1.0")
- **minor** component version: `KbxFastEntryPage` ("1.0.0" → "1.7.0")
- **minor** component version: `KbxQueuePage` ("1.0.0" → "1.6.0")
- **minor** screen added: `ERP-PRICE-001`
- **major** screen templateCode: `COMMON-DATA-001` (null → "T01")
- **major** screen templateCode: `COMMON-DS-001` (null → "T01")
- **major** screen templateCode: `COMMON-EXP-001` (null → "T01")
- **major** screen templateCode: `COMMON-OPS-001` (null → "T06")
- **major** screen templateCode: `COMMON-REC-001` (null → "T07")
- **major** screen templateCode: `COMMON-UX-001` (null → "T01")
- **patch** screen version: `ERP-INV-001` ("1.0.0" → "1.1.0")
- **major** screen templateCode: `ERP-INV-001` (null → "T05")
- **major** screen templateCode: `ERP-INV-MOVE-001` (null → "T03")
- **patch** screen version: `ERP-MST-ITEM-001` ("1.0.0" → "1.1.0")
- **major** screen templateCode: `ERP-MST-ITEM-001` (null → "T02")
- **major** screen templateCode: `ERP-PUR-001` (null → "T03")
- **major** screen templateCode: `OMS-CLM-001` (null → "T01")
- **patch** screen version: `OMS-ORD-001` ("1.0.0" → "1.1.0")
- **major** screen templateCode: `OMS-ORD-001` (null → "T01")
- **patch** screen version: `OMS-ORD-002` ("1.1.0" → "1.3.0")
- **major** screen templateCode: `OMS-ORD-002` (null → "T03")
- **major** screen templateCode: `OMS-ORD-003` (null → "T08")
- **major** screen templateCode: `WMS-COUNT-001` (null → "T09")
- **major** screen templateCode: `WMS-PICK-001` (null → "T09")
- **major** screen templateCode: `WMS-PUT-001` (null → "T09")
- **major** screen templateCode: `WMS-REC-001` (null → "T09")
- **major** screen templateCode: `WMS-WORK-001` (null → "T06")
- **minor** screen-recipe added: `T01`
- **minor** screen-recipe added: `T02`
- **minor** screen-recipe added: `T03`
- **minor** screen-recipe added: `T04`
- **minor** screen-recipe added: `T05`
- **minor** screen-recipe added: `T06`
- **minor** screen-recipe added: `T07`
- **minor** screen-recipe added: `T08`
- **minor** screen-recipe added: `T09`
- **minor** token added: `semantic.status.infoSurface`
- **minor** token added: `semantic.status.infoBorder`
- **minor** token added: `semantic.status.successSurface`
- **minor** token added: `semantic.status.successBorder`
- **minor** token added: `semantic.status.warningSurface`
- **minor** token added: `semantic.status.warningBorder`
- **minor** token added: `semantic.status.warningText`
- **minor** token added: `semantic.status.dangerSurface`
- **minor** token added: `semantic.status.dangerBorder`
- **minor** token added: `border.width.default`
- **minor** token added: `border.width.accent`
- **minor** token added: `radius.pill`
- **minor** token added: `component.control.xs`
- **minor** token added: `component.control.sm`
- **minor** token added: `component.control.md`
- **minor** token added: `component.control.lg`
- **minor** token added: `component.form.textareaMinHeight`
- **minor** token added: `component.checkbox.size`
- **minor** token added: `component.checkbox.track`
- **minor** token added: `component.screen.inlinePadding`
- **minor** token added: `component.screen.sectionGap`
- **minor** token added: `component.screen.contentMinHeight`
- **minor** token added: `component.master.listMinWidth`
- **minor** token added: `component.master.listCompactWidth`
- **minor** token added: `component.master.masterWidth`
- **minor** token added: `component.masterDetail.minHeight`
- **minor** token added: `component.masterDetail.bottomMinHeight`
- **minor** token added: `component.masterDetail.masterMinSm`
- **minor** token added: `component.masterDetail.masterMinMd`
- **minor** token added: `component.masterDetail.masterMinLg`
- **minor** token added: `component.navigation.sideWidth`
- **minor** token added: `component.navigation.sideCollapsedWidth`
- **minor** token added: `component.home.maxWidth`
- **minor** token added: `component.home.searchMaxWidth`
- **minor** token added: `component.home.headerMinHeight`
- **minor** token added: `component.home.attentionHeight`
- **minor** token added: `component.home.linkHeight`
- **minor** token added: `component.home.moduleColumn`
- **minor** token added: `component.home.moduleHeaderHeight`
- **minor** token added: `component.tooltip.maxWidth`
- **minor** token added: `component.access.maxWidth`
- **minor** token added: `component.wms.mobileMaxWidth`
- **minor** token added: `component.wms.headerMinHeight`
- **minor** token added: `semantic.state.changedSurface`
- **minor** token added: `semantic.state.changedBorder`
- **minor** token added: `semantic.state.aiSurface`
- **minor** token added: `semantic.state.aiBorder`
- **minor** token added: `semantic.state.aiText`
- **minor** token added: `component.dataState.minHeight`
- **minor** token added: `component.grid.toolbarHeight`
- **minor** token added: `component.grid.minHeight`
- **minor** token added: `component.lookup.codeWidth`
- **minor** token added: `component.lookup.nameMinWidth`
- **minor** token added: `component.lookup.buttonWidth`
- **minor** token added: `component.search.controlMinWidth`
- **minor** token added: `component.search.controlSmWidth`
- **minor** token added: `component.search.controlLgWidth`
- **minor** token added: `component.command.separatorHeight`
- **minor** token added: `component.template.contextMinHeight`
- **minor** token added: `component.progress.stepHeight`
- **minor** token added: `component.progress.stepNumberSize`
- **minor** token added: `component.menuSearch.top`
- **minor** token added: `component.menuSearch.width`
- **minor** token added: `component.menuSearch.resultHeight`
- **minor** token added: `component.application.minHeight`
- **minor** token added: `component.runtime.panelTop`
- **minor** token added: `component.runtime.panelWidth`
- **minor** token added: `component.workspace.tabsHeight`
- **minor** token added: `component.workspace.tabHeight`
- **minor** token added: `component.workspace.tabMaxWidth`
- **minor** token added: `component.workspace.overflowWidth`
- **minor** token added: `semantic.shadow.overlay`
- **minor** token added: `semantic.z.runtimePanel`
- **minor** token added: `component.template.refreshHeight`
- **minor** token added: `component.home.quickStartMinHeight`
- **minor** token added: `component.shell.noticeHeight`
- **minor** token added: `component.home.moduleLabelWidth`
- **minor** token added: `component.utility.panelWidth`
- **minor** token added: `semantic.accessibility.visuallyHiddenSize`
- **minor** token added: `component.form.sectionGap`
- **minor** token added: `component.form.sectionHeadingGap`
- **minor** token added: `component.form.sectionHeadingPadding`
- **minor** token added: `component.form.gridColumnGap`
- **minor** token added: `component.form.gridRowGap`
- **minor** token added: `component.home.workbenchRowHeight`
- **minor** token added: `component.home.sourceLabelWidth`
- **minor** token added: `component.navigation.securityNoticeHeight`
- **minor** token added: `component.globalHeader.moduleSelectorWidth`
- **minor** token added: `component.import.dropMinHeight`
- **minor** token added: `component.import.sourceColumnMinWidth`
- **minor** token added: `component.import.targetColumnMinWidth`
- **minor** token added: `component.import.reasonColumnMinWidth`
- **minor** token added: `component.import.mappingNameWidth`
- **minor** token added: `component.summary.itemMinWidth`
- **minor** token added: `component.import.errorRowWidth`
- **minor** token added: `component.import.errorFieldWidth`
- **minor** token added: `component.wms.scanBoxMinHeight`
- **minor** token added: `component.wms.manualButtonWidth`
- **minor** field added: `effectiveDate`
- **major** api permission: `lookup.items.resolveByCode` ("oms.order.read" → "erp.item.read")
- **major** api permission: `lookup.items.resolveById` ("oms.order.read" → "erp.item.read")
- **major** api permission: `lookup.items.search` ("oms.order.read" → "erp.item.read")
- **minor** api added: `erp.inventory.history`
- **minor** api added: `erp.itemPrices.bulkSave`
- **minor** api added: `erp.items.create`
- **minor** api added: `erp.items.update`
- **minor** api added: `erp.items.deactivate`
- **minor** api added: `erp.items.audit`
- **minor** api added: `oms.orders.get`
- **minor** api added: `oms.orders.confirm`
- **minor** api added: `oms.orders.audit`
- **minor** api added: `oms.orders.update`
- **minor** permission added: `erp.item.price.read`
- **minor** permission added: `erp.item.price.write`
- **minor** permission added: `oms.order.confirm`
- **minor** permission added: `oms.order.write`
- **minor** configuration-setting added: `Kbx:Runtime:Environment`
- **minor** configuration-setting added: `Kbx:Runtime:ReadOnly`
- **minor** configuration-setting added: `ConnectionStrings:Main`
- **minor** configuration-setting added: `Kbx:Database:MigrationsMode`
- **minor** configuration-setting added: `Kbx:Database:CommandTimeoutSeconds`
- **minor** configuration-setting added: `Kbx:Hangfire:Enabled`
- **minor** configuration-setting added: `Kbx:Hangfire:WorkerCount`
- **minor** configuration-setting added: `Kbx:SignalR:Enabled`
- **minor** configuration-setting added: `Kbx:Outbox:DispatcherEnabled`
- **minor** configuration-setting added: `Kbx:Inbox:CleanupEnabled`
- **minor** configuration-setting added: `Kbx:Integration:DispatcherEnabled`
- **minor** configuration-setting added: `Kbx:ExternalData:RefreshEnabled`
- **minor** configuration-setting added: `Kbx:ExternalData:ObservationRetentionEnabled`
- **minor** configuration-setting added: `Kbx:Experiments:Enabled`
- **minor** configuration-setting added: `Kbx:Logging:MinimumLevel`
- **minor** configuration-setting added: `Kbx:Logging:JsonConsoleEnabled`
- **minor** configuration-setting added: `Kbx:Telemetry:Enabled`
- **minor** configuration-setting added: `Kbx:Telemetry:OtlpEndpoint`
- **minor** configuration-setting added: `Kbx:Telegram:Enabled`
- **minor** configuration-setting added: `Kbx:Telegram:BotToken`
- **minor** configuration-setting added: `Kbx:Telegram:ChatId`
- **minor** configuration-setting added: `ExternalProviders:Krx:Enabled`
- **minor** configuration-setting added: `ExternalProviders:Krx:AuthKey`
- **minor** configuration-setting added: `ExternalProviders:OpenDart:Enabled`
- **minor** configuration-setting added: `ExternalProviders:OpenDart:ApiKey`
- **minor** configuration-setting added: `ExternalProviders:Kis:Enabled`
- **minor** configuration-setting added: `ExternalProviders:Kis:Environment`
- **minor** configuration-setting added: `ExternalProviders:Kis:AppKey`
- **minor** configuration-setting added: `ExternalProviders:Kis:AppSecret`
- **minor** configuration-setting added: `Kbx:Security:RequireHttps`
- **minor** configuration-setting added: `Kbx:Health:ReadinessEnabled`
- **minor** configuration-setting added: `Kbx:Import:MaxUploadBytes`
- **minor** configuration-setting added: `Kbx:Import:MaxRows`
- **minor** environment-profile added: `Development`
- **minor** environment-profile added: `Test`
- **minor** environment-profile added: `Staging`
- **minor** environment-profile added: `Production`
- **patch** test-scenario added: `scenario.common.design-system.interactions`
- **patch** test-scenario added: `scenario.erp.inventory.master-detail-context`
- **patch** test-scenario added: `scenario.erp.item-price.fast-entry`
- **patch** test-scenario added: `scenario.oms.order-list.all-filtered-ship`
- **patch** test-scenario contract: `scenario.oms.order-register.conflict`
- **patch** test-scenario added: `scenario.oms.order-register.fast-entry`
- **patch** test-scenario contract: `scenario.oms.order-register.keyboard`
- **patch** test-scenario contract: `scenario.shell.unsaved-tab`
- **patch** test-scenario added: `scenario.erp.item-master.lifecycle`
- **patch** test-scenario added: `scenario.oms.order-register.lifecycle`
- **patch** test-scenario added: `scenario.shell.home-navigation-security`
- **patch** test-scenario added: `scenario.kbx.template-runtime-utility`
- **patch** test-scenario added: `scenario.common.design-system.form-composition`
- **patch** test-scenario added: `scenario.shell.module-route-recovery`
- **patch** test-scenario added: `scenario.erp.item-master.keyboard-recovery`
- **patch** test-scenario added: `scenario.common.operations.queue-recovery`
- **patch** test-scenario added: `scenario.common.reconcile.mismatch-recovery`
## Governance additions
- Canonical permission catalog + Screen/Command/Workflow/API parity
- Sensitive data policy + audited disclosure
- AI effective-permission intersection
- KbxMaskedValue masking UX
- Permission/Sensitive-policy release compatibility analysis
- Semantic UX telemetry + Manual Intervention Rate governance
- Safe UX experiment + controlled rollout + kill-switch governance
- Deterministic synthetic fixture + executable scenario governance
- External integration + resilience governance
- Official-source external provider adapters + provider contract governance
- External data normalization + provenance + freshness governance
- Deployment configuration + environment promotion governance
@@ -0,0 +1,264 @@
[
{
"id": "COMMON-DATA-001",
"version": "1.0.0",
"module": "COMMON",
"type": "list",
"templateCode": "T01",
"title": "외부 데이터 상태",
"helpKey": "COMMON-DATA-001",
"requiredPermissions": [
"common.external-data.read"
],
"source": "apps/web/src/modules/common/external-data/external-data.definition.ts"
},
{
"id": "COMMON-DS-001",
"version": "1.0.0",
"module": "COMMON",
"type": "list",
"templateCode": "T01",
"title": "KBX 컴포넌트 카탈로그",
"helpKey": "COMMON-DS-001",
"requiredPermissions": [
"kbx.design.read"
],
"source": "apps/web/src/modules/common/design-system/design-system.definition.ts"
},
{
"id": "COMMON-EXP-001",
"version": "1.0.0",
"module": "COMMON",
"type": "list",
"templateCode": "T01",
"title": "UX 실험·점진배포",
"helpKey": "COMMON-EXP-001",
"requiredPermissions": [
"common.experiment.read"
],
"source": "apps/web/src/modules/common/experiments/experiments.definition.ts"
},
{
"id": "COMMON-OPS-001",
"version": "1.0.0",
"module": "COMMON",
"type": "queue",
"templateCode": "T06",
"title": "업무 예외 센터",
"helpKey": "COMMON-OPS-001",
"requiredPermissions": [
"common.operations.read"
],
"source": "apps/web/src/modules/common/operations/operations.definition.ts"
},
{
"id": "COMMON-REC-001",
"version": "1.0.0",
"module": "COMMON",
"type": "reconcile",
"templateCode": "T07",
"title": "업무 데이터 대사",
"helpKey": "COMMON-REC-001",
"requiredPermissions": [
"common.reconcile.read"
],
"source": "apps/web/src/modules/common/reconcile/reconcile.definition.ts"
},
{
"id": "COMMON-UX-001",
"version": "1.0.0",
"module": "COMMON",
"type": "list",
"templateCode": "T01",
"title": "UX 품질 지표",
"helpKey": "COMMON-UX-001",
"requiredPermissions": [
"common.ux.read"
],
"source": "apps/web/src/modules/common/ux-metrics/ux-metrics.definition.ts"
},
{
"id": "ERP-INV-001",
"version": "1.1.0",
"module": "ERP",
"type": "master-detail",
"templateCode": "T05",
"title": "재고현황",
"helpKey": "ERP-INV-001",
"requiredPermissions": [
"erp.inventory.read"
],
"source": "apps/web/src/modules/erp/inventory/inventory.definition.ts"
},
{
"id": "ERP-INV-MOVE-001",
"version": "1.0.0",
"module": "ERP",
"type": "transaction",
"templateCode": "T03",
"title": "재고이동",
"helpKey": "ERP-INV-MOVE-001",
"requiredPermissions": [
"erp.inventory.move.read"
],
"source": "apps/web/src/modules/erp/inventory-move/inventory-move.definition.ts"
},
{
"id": "ERP-MST-ITEM-001",
"version": "1.1.0",
"module": "ERP",
"type": "master",
"templateCode": "T02",
"title": "품목관리",
"helpKey": "ERP-MST-ITEM-001",
"requiredPermissions": [
"erp.item.read"
],
"source": "apps/web/src/modules/erp/items/item.definition.ts"
},
{
"id": "ERP-PRICE-001",
"version": "1.0.0",
"module": "ERP",
"type": "fast-entry",
"templateCode": "T04",
"title": "품목 단가 일괄등록",
"helpKey": "ERP-PRICE-001",
"requiredPermissions": [
"erp.item.price.read",
"erp.item.read"
],
"source": "apps/web/src/modules/erp/item-prices/item-price.definition.ts"
},
{
"id": "ERP-PUR-001",
"version": "1.0.0",
"module": "ERP",
"type": "transaction",
"templateCode": "T03",
"title": "구매등록",
"helpKey": "ERP-PUR-001",
"requiredPermissions": [
"erp.purchase.read"
],
"source": "apps/web/src/modules/erp/purchases/purchase.definition.ts"
},
{
"id": "OMS-CLM-001",
"version": "1.0.0",
"module": "OMS",
"type": "list",
"templateCode": "T01",
"title": "반품·클레임 관리",
"helpKey": "OMS-CLM-001",
"requiredPermissions": [
"oms.claim.read"
],
"source": "apps/web/src/modules/oms/claims/claims.definition.ts"
},
{
"id": "OMS-ORD-001",
"version": "1.1.0",
"module": "OMS",
"type": "list",
"templateCode": "T01",
"title": "주문관리",
"helpKey": "OMS-ORD-001",
"requiredPermissions": [
"oms.order.read"
],
"source": "apps/web/src/modules/oms/orders/search/order-list.definition.ts"
},
{
"id": "OMS-ORD-002",
"version": "1.3.0",
"module": "OMS",
"type": "transaction",
"templateCode": "T03",
"title": "주문등록",
"helpKey": "OMS-ORD-002",
"requiredPermissions": [
"oms.order.read",
"erp.item.read"
],
"source": "apps/web/src/modules/oms/orders/register/order-register.definition.ts"
},
{
"id": "OMS-ORD-003",
"version": "1.1.0",
"module": "OMS",
"type": "import",
"templateCode": "T08",
"title": "주문 Excel 업로드",
"helpKey": "OMS-ORD-003",
"requiredPermissions": [
"oms.order.import"
],
"source": "apps/web/src/modules/oms/orders/import/order-import.definition.ts"
},
{
"id": "WMS-COUNT-001",
"version": "1.0.0",
"module": "WMS",
"type": "wms-mobile",
"templateCode": "T09",
"title": "재고실사",
"helpKey": "WMS-COUNT-001",
"requiredPermissions": [
"wms.inventory.count"
],
"source": "apps/web/src/modules/wms/counting/counting.definition.ts"
},
{
"id": "WMS-PICK-001",
"version": "1.0.0",
"module": "WMS",
"type": "wms-mobile",
"templateCode": "T09",
"title": "출고 피킹",
"helpKey": "WMS-PICK-001",
"requiredPermissions": [
"wms.picking.execute"
],
"source": "apps/web/src/modules/wms/picking/picking.definition.ts"
},
{
"id": "WMS-PUT-001",
"version": "1.0.0",
"module": "WMS",
"type": "wms-mobile",
"templateCode": "T09",
"title": "입고 적치",
"helpKey": "WMS-PUT-001",
"requiredPermissions": [
"wms.putaway.execute"
],
"source": "apps/web/src/modules/wms/putaway/putaway.definition.ts"
},
{
"id": "WMS-REC-001",
"version": "1.0.0",
"module": "WMS",
"type": "wms-mobile",
"templateCode": "T09",
"title": "입고 검수",
"helpKey": "WMS-REC-001",
"requiredPermissions": [
"wms.receiving.execute"
],
"source": "apps/web/src/modules/wms/receiving/receiving.definition.ts"
},
{
"id": "WMS-WORK-001",
"version": "1.0.0",
"module": "WMS",
"type": "queue",
"templateCode": "T06",
"title": "물류 작업",
"helpKey": "WMS-WORK-001",
"requiredPermissions": [
"wms.work.read"
],
"source": "apps/web/src/modules/wms/work/work.definition.ts"
}
]
@@ -0,0 +1,608 @@
{
"schemaVersion": 1,
"contractVersion": "1.1.0",
"sourceSha256": "97ab56bc54149f32ea16577369c4ec29579b516ea464cb42010b31e4dc413e60",
"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,355 @@
{
"schemaVersion": 1,
"recipeContractVersion": "1.1.0",
"scenarioContractVersion": "1.9.0",
"recipeSourceSha256": "97ab56bc54149f32ea16577369c4ec29579b516ea464cb42010b31e4dc413e60",
"scenarioSourceSha256": "c2a8910c136f08c0c33c3f7f5e78302a0723a35ab8506c3dbdee53634e2c5df3",
"recipes": [
{
"code": "T01",
"type": "list",
"canonicalScenarioIds": [
"scenario.oms.order-list.bulk-ship",
"scenario.oms.order-list.all-filtered-ship"
],
"scenarioKinds": [
"contract",
"e2e"
],
"tags": [
"all-filtered",
"audit",
"bulk",
"filter-snapshot",
"golden-screen",
"idempotency",
"outbox"
],
"evidence": [
"api-transcript",
"correlation-ids",
"db-assertions",
"playwright-trace",
"screenshot",
"vitest-contract"
],
"requiredChecks": [
"idle-search",
"refresh-retains-context",
"bulk-partial-result",
"safe-drilldown"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T02",
"type": "master",
"canonicalScenarioIds": [
"scenario.erp.item-master.lifecycle",
"scenario.erp.item-master.keyboard-recovery"
],
"scenarioKinds": [
"e2e",
"integration"
],
"tags": [
"audit",
"concurrency",
"golden-screen",
"keyboard",
"master-crud",
"permission",
"recovery",
"state-policy"
],
"evidence": [
"api-transcript",
"db-assertions",
"playwright-trace",
"problem-json",
"screenshot"
],
"requiredChecks": [
"permission-aware-save",
"dirty-guard",
"conflict-reload",
"audit-visible"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T03",
"type": "transaction",
"canonicalScenarioIds": [
"scenario.oms.order-register.keyboard",
"scenario.oms.order-register.conflict",
"scenario.oms.order-register.lifecycle"
],
"scenarioKinds": [
"e2e",
"integration"
],
"tags": [
"audit",
"concurrency",
"conflict",
"golden-screen",
"keyboard",
"lookup",
"recovery",
"state-policy",
"transaction",
"validation",
"workflow"
],
"evidence": [
"api-transcript",
"db-assertions",
"playwright-trace",
"problem-json",
"screenshot"
],
"requiredChecks": [
"f2-lookup",
"f8-save",
"row-key-validation",
"conflict-recovery"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T04",
"type": "fast-entry",
"canonicalScenarioIds": [
"scenario.erp.item-price.fast-entry",
"scenario.oms.order-register.fast-entry"
],
"scenarioKinds": [
"contract",
"e2e"
],
"tags": [
"audit",
"fast-entry",
"fill-down",
"golden-screen",
"idempotency",
"inline-validation",
"lookup",
"outbox",
"paste"
],
"evidence": [
"api-transcript",
"component-catalog",
"db-assertions",
"playwright-trace",
"problem-json",
"vitest-contract"
],
"requiredChecks": [
"multi-cell-paste",
"fill-down",
"error-navigation",
"partial-save-result"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T05",
"type": "master-detail",
"canonicalScenarioIds": [
"scenario.erp.inventory.master-detail-context"
],
"scenarioKinds": [
"e2e"
],
"tags": [
"context-retention",
"drill-down",
"golden-screen",
"history",
"master-detail"
],
"evidence": [
"api-transcript",
"playwright-trace",
"screenshot"
],
"requiredChecks": [
"master-selection-context",
"detail-error-retains-master",
"history-context",
"safe-drilldown"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T06",
"type": "queue",
"canonicalScenarioIds": [
"scenario.common.operations.stale-event",
"scenario.integration.manual-retry.idempotent",
"scenario.common.operations.queue-recovery"
],
"scenarioKinds": [
"e2e",
"integration"
],
"tags": [
"context-retention",
"exception",
"golden-screen",
"idempotency",
"integration",
"manual-retry",
"ordering",
"outbox",
"permission",
"projection",
"queue",
"recovery"
],
"evidence": [
"api-transcript",
"correlation-ids",
"db-assertions",
"playwright-trace",
"projection-event-log",
"screenshot"
],
"requiredChecks": [
"exception-first",
"detail-context-retention",
"retryable-vs-terminal",
"partial-action-result"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T07",
"type": "reconcile",
"canonicalScenarioIds": [
"scenario.common.reconcile.grace-period",
"scenario.common.reconcile.mismatch-recovery"
],
"scenarioKinds": [
"e2e",
"integration"
],
"tags": [
"context-retention",
"eventual-consistency",
"golden-screen",
"mismatch-filter",
"reconcile",
"recovery"
],
"evidence": [
"api-transcript",
"clock-snapshot",
"db-assertions",
"playwright-trace",
"screenshot"
],
"requiredChecks": [
"mismatch-only-filter",
"grace-period",
"resolution-retry",
"comparison-context"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T08",
"type": "import",
"canonicalScenarioIds": [
"scenario.oms.order-import.partial"
],
"scenarioKinds": [
"e2e"
],
"tags": [
"excel",
"job",
"mapping",
"partial-success",
"staging"
],
"evidence": [
"api-transcript",
"db-assertions",
"error-workbook-metadata",
"import-session-snapshot",
"playwright-trace",
"problem-json"
],
"requiredChecks": [
"mapping-isolation",
"validation-download",
"commit-confirm",
"job-refresh-recovery"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
},
{
"code": "T09",
"type": "wms-mobile",
"canonicalScenarioIds": [
"scenario.wms.picking.idempotent-replay",
"scenario.wms.picking.wrong-item"
],
"scenarioKinds": [
"e2e"
],
"tags": [
"business-error",
"golden-screen",
"idempotency",
"network",
"retry-policy",
"scanner"
],
"evidence": [
"api-transcript",
"db-assertions",
"playwright-trace",
"scanner-event-log"
],
"requiredChecks": [
"scan-normalization",
"server-before-success",
"response-loss-replay",
"wrong-item-no-retry"
],
"missingScenarioKinds": [],
"missingTags": [],
"missingEvidence": [],
"complete": true
}
]
}
@@ -0,0 +1,33 @@
{
"schemaVersion": "1.0",
"policies": [
{
"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,294 @@
{
"schemaVersion": "1.0",
"telemetryVersion": "1.1.0",
"sourceSha256": "9f5de69498b657cb0d60df18c1e98c504a44eec555c4fc50d46f15f83a4ea1ce",
"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,142 @@
{
"schemaVersion": "1.0",
"fixtureVersion": "1.4.0",
"sourceSha256": "befb917413e52c04f3d0116f29aa2f07d3273d6b71d980a4f4416d48a5b3a162",
"syntheticOnly": true,
"fixedReferenceClock": "2026-08-08T09:00:00Z",
"testTenant": {
"id": "11111111-1111-4111-8111-111111111111",
"key": "KBX-TEST-TENANT"
},
"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"
]
}
],
"refCount": 37
}
@@ -0,0 +1,885 @@
{
"schemaVersion": "1.0",
"contractVersion": "1.9.0",
"sourceSha256": "c2a8910c136f08c0c33c3f7f5e78302a0723a35ab8506c3dbdee53634e2c5df3",
"fixtureVersion": "1.4.0",
"fixtureSourceSha256": "befb917413e52c04f3d0116f29aa2f07d3273d6b71d980a4f4416d48a5b3a162",
"fixedReferenceClock": "2026-08-08T09:00:00Z",
"scenarios": [
{
"id": "scenario.common.design-system.interactions",
"title": "KBX 컴포넌트 상태·키보드 상호작용 계약",
"screenId": "COMMON-DS-001",
"kind": "e2e",
"tags": [
"component-contract",
"accessibility",
"keyboard",
"visual-regression"
],
"fixtureSets": [],
"requiredPermissions": [],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 4,
"evidence": [
"playwright-trace",
"screenshot"
]
},
{
"id": "scenario.common.operations.stale-event",
"title": "업무 예외 해결 후 오래된 Event가 재오픈하지 않음",
"screenId": "COMMON-OPS-001",
"kind": "integration",
"tags": [
"exception",
"outbox",
"projection",
"ordering"
],
"fixtureSets": [
"fixture.common.operations"
],
"requiredPermissions": [
"common.operations.read",
"common.operations.resolve"
],
"apiOperations": [
"common.operations.search"
],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"db-assertions",
"projection-event-log"
]
},
{
"id": "scenario.common.reconcile.grace-period",
"title": "OMS-WMS 대사 Grace Period 내 Pending 이후 Mismatch",
"screenId": "COMMON-REC-001",
"kind": "integration",
"tags": [
"reconcile",
"eventual-consistency"
],
"fixtureSets": [
"fixture.common.reconcile"
],
"requiredPermissions": [
"common.reconcile.read"
],
"apiOperations": [
"common.reconcile.search"
],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"db-assertions",
"clock-snapshot"
]
},
{
"id": "scenario.erp.inventory-move.workflow",
"title": "ERP 재고이동 정상 상태전이와 잘못된 창고 차단",
"screenId": "ERP-INV-MOVE-001",
"kind": "integration",
"tags": [
"workflow",
"domain-validation",
"audit"
],
"fixtureSets": [
"fixture.erp.inventory-move"
],
"requiredPermissions": [
"erp.inventory.move.read",
"erp.inventory.move.write"
],
"apiOperations": [],
"isolation": "database-reset",
"assertionCount": 3,
"evidence": [
"db-assertions",
"workflow-log"
]
},
{
"id": "scenario.erp.inventory.master-detail-context",
"title": "ERP 재고 T05 Master/Detail Context·이력·Drill-down",
"screenId": "ERP-INV-001",
"kind": "e2e",
"tags": [
"golden-screen",
"master-detail",
"context-retention",
"drill-down",
"history"
],
"fixtureSets": [
"fixture.erp.inventory-explorer"
],
"requiredPermissions": [
"erp.inventory.read"
],
"apiOperations": [
"erp.inventory.search",
"erp.inventory.locations",
"erp.inventory.history"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"playwright-trace",
"screenshot",
"api-transcript"
]
},
{
"id": "scenario.erp.item-price.fast-entry",
"title": "ERP 품목 단가 T04 Fast Entry 일괄저장",
"screenId": "ERP-PRICE-001",
"kind": "e2e",
"tags": [
"golden-screen",
"fast-entry",
"lookup",
"paste",
"fill-down",
"idempotency",
"audit",
"outbox"
],
"fixtureSets": [
"fixture.erp.item-price-fast-entry"
],
"requiredPermissions": [
"erp.item.price.read",
"erp.item.price.write",
"erp.item.read"
],
"apiOperations": [
"lookup.items.resolveByCode",
"erp.itemPrices.bulkSave"
],
"isolation": "database-reset",
"assertionCount": 6,
"evidence": [
"playwright-trace",
"api-transcript",
"db-assertions",
"problem-json"
]
},
{
"id": "scenario.external-data.kis.strict-expiry",
"title": "KIS 현재가 만료 캐시를 최신값으로 사용하지 않음",
"screenId": "COMMON-DATA-001",
"kind": "integration",
"tags": [
"external-data",
"kis",
"freshness",
"strict"
],
"fixtureSets": [
"fixture.external-data.kis"
],
"requiredPermissions": [
"common.external-data.read"
],
"apiOperations": [
"common.externalData.status"
],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"api-transcript",
"db-assertions",
"external-data-provenance"
]
},
{
"id": "scenario.external-data.opendart.stale-revalidate",
"title": "OPENDART Stale 데이터 명시 표시 후 재수집 예약",
"screenId": "COMMON-DATA-001",
"kind": "integration",
"tags": [
"external-data",
"opendart",
"stale-while-revalidate",
"provenance"
],
"fixtureSets": [
"fixture.external-data.opendart"
],
"requiredPermissions": [
"common.external-data.read",
"common.external-data.refresh"
],
"apiOperations": [
"common.externalData.status",
"common.externalData.refresh"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"api-transcript",
"db-assertions",
"external-data-provenance"
]
},
{
"id": "scenario.integration.inbox.duplicate",
"title": "Inbox 동일 메시지 중복수신 1회 처리",
"screenId": "COMMON-OPS-001",
"kind": "integration",
"tags": [
"integration",
"inbox",
"idempotency",
"duplicate"
],
"fixtureSets": [
"fixture.integration.inbox"
],
"requiredPermissions": [
"common.operations.read"
],
"apiOperations": [],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"db-assertions",
"integration-receipt-log",
"correlation-ids"
]
},
{
"id": "scenario.integration.manual-retry.idempotent",
"title": "최종 실패 외부연계 수동 재처리 중복 클릭 방지",
"screenId": "COMMON-OPS-001",
"kind": "integration",
"tags": [
"integration",
"manual-retry",
"idempotency"
],
"fixtureSets": [
"fixture.integration.outbox"
],
"requiredPermissions": [
"common.integration.read",
"common.integration.retry"
],
"apiOperations": [
"common.integrations.retryAttempt"
],
"isolation": "database-reset",
"assertionCount": 3,
"evidence": [
"api-transcript",
"db-assertions",
"correlation-ids"
]
},
{
"id": "scenario.integration.outbox.permanent-failure",
"title": "외부연계 영구 실패가 업무 예외로 승격",
"screenId": "COMMON-OPS-001",
"kind": "integration",
"tags": [
"integration",
"outbox",
"permanent-failure",
"exception"
],
"fixtureSets": [
"fixture.integration.outbox"
],
"requiredPermissions": [
"common.operations.read"
],
"apiOperations": [],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"db-assertions",
"integration-attempt-log",
"correlation-ids"
]
},
{
"id": "scenario.integration.outbox.transient-retry",
"title": "Outbox 외부연계 일시 장애 후 자동 재시도",
"screenId": "COMMON-OPS-001",
"kind": "integration",
"tags": [
"integration",
"outbox",
"retry",
"polly",
"hangfire"
],
"fixtureSets": [
"fixture.integration.outbox"
],
"requiredPermissions": [
"common.operations.read"
],
"apiOperations": [],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"api-transcript",
"db-assertions",
"integration-attempt-log",
"correlation-ids"
]
},
{
"id": "scenario.oms.order-import.partial",
"title": "OMS 주문 Excel 검증 후 부분 반영",
"screenId": "OMS-ORD-003",
"kind": "e2e",
"tags": [
"excel",
"mapping",
"staging",
"partial-success",
"job"
],
"fixtureSets": [
"fixture.oms.order-import"
],
"requiredPermissions": [
"oms.order.import"
],
"apiOperations": [
"common.imports.createSession",
"common.imports.validate",
"common.imports.commit",
"common.imports.getSession"
],
"isolation": "database-reset",
"assertionCount": 7,
"evidence": [
"playwright-trace",
"api-transcript",
"import-session-snapshot",
"error-workbook-metadata",
"db-assertions",
"problem-json"
]
},
{
"id": "scenario.oms.order-list.all-filtered-ship",
"title": "OMS 주문조회 검색결과 전체선택 안전 출고 계약",
"screenId": "OMS-ORD-001",
"kind": "contract",
"tags": [
"golden-screen",
"bulk",
"all-filtered",
"filter-snapshot",
"idempotency"
],
"fixtureSets": [
"fixture.oms.orders.bulk-ship"
],
"requiredPermissions": [
"oms.order.read",
"oms.order.ship"
],
"apiOperations": [
"oms.orders.search",
"oms.orders.ship"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"vitest-contract",
"api-transcript",
"db-assertions",
"correlation-ids"
]
},
{
"id": "scenario.oms.order-list.bulk-ship",
"title": "OMS 주문조회 대량 출고지시 부분성공",
"screenId": "OMS-ORD-001",
"kind": "e2e",
"tags": [
"golden-screen",
"bulk",
"idempotency",
"audit",
"outbox"
],
"fixtureSets": [
"fixture.oms.orders.bulk-ship"
],
"requiredPermissions": [
"oms.order.read",
"oms.order.ship"
],
"apiOperations": [
"oms.orders.search",
"oms.orders.ship"
],
"isolation": "database-reset",
"assertionCount": 7,
"evidence": [
"playwright-trace",
"screenshot",
"api-transcript",
"db-assertions",
"correlation-ids"
]
},
{
"id": "scenario.oms.order-register.conflict",
"title": "OMS 주문수정 Optimistic Concurrency 충돌",
"screenId": "OMS-ORD-002",
"kind": "integration",
"tags": [
"concurrency",
"conflict",
"recovery"
],
"fixtureSets": [
"fixture.oms.order-conflict"
],
"requiredPermissions": [
"oms.order.read",
"erp.item.read",
"oms.order.write"
],
"apiOperations": [
"oms.orders.update",
"oms.orders.get"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"api-transcript",
"db-assertions",
"problem-json"
]
},
{
"id": "scenario.oms.order-register.fast-entry",
"title": "OMS 주문등록 Fast Entry Grid 대량입력 계약",
"screenId": "OMS-ORD-002",
"kind": "contract",
"tags": [
"golden-screen",
"fast-entry",
"paste",
"fill-down",
"inline-validation"
],
"fixtureSets": [
"fixture.oms.order-register"
],
"requiredPermissions": [
"oms.order.create",
"oms.order.read"
],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 5,
"evidence": [
"vitest-contract",
"playwright-trace",
"component-catalog"
]
},
{
"id": "scenario.oms.order-register.keyboard",
"title": "OMS 주문등록 키보드 중심 저장",
"screenId": "OMS-ORD-002",
"kind": "e2e",
"tags": [
"golden-screen",
"keyboard",
"lookup",
"validation",
"audit"
],
"fixtureSets": [
"fixture.oms.order-register"
],
"requiredPermissions": [
"oms.order.create",
"oms.order.read",
"erp.item.read"
],
"apiOperations": [
"lookup.customers.search",
"lookup.items.resolveByCode",
"lookup.warehouses.resolveByCode",
"oms.orders.register"
],
"isolation": "database-reset",
"assertionCount": 6,
"evidence": [
"playwright-trace",
"screenshot",
"api-transcript",
"db-assertions"
]
},
{
"id": "scenario.shell.unsaved-tab",
"title": "Workspace Tab 미저장 변경 보호",
"screenId": "OMS-ORD-002",
"kind": "e2e",
"tags": [
"shell",
"dirty-state",
"keyboard"
],
"fixtureSets": [
"fixture.shell.user"
],
"requiredPermissions": [
"oms.order.create",
"oms.order.read",
"erp.item.read"
],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 4,
"evidence": [
"playwright-trace",
"screenshot"
]
},
{
"id": "scenario.wms.picking.idempotent-replay",
"title": "WMS 피킹 응답유실 후 동일 Scan Replay",
"screenId": "WMS-PICK-001",
"kind": "e2e",
"tags": [
"golden-screen",
"scanner",
"idempotency",
"network"
],
"fixtureSets": [
"fixture.wms.picking"
],
"requiredPermissions": [
"wms.picking.execute"
],
"apiOperations": [
"wms.picking.getTask",
"wms.picking.start",
"wms.picking.scan"
],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"playwright-trace",
"api-transcript",
"db-assertions",
"scanner-event-log"
]
},
{
"id": "scenario.wms.picking.wrong-item",
"title": "WMS 다른 상품 Scan은 재시도 Queue 비대상",
"screenId": "WMS-PICK-001",
"kind": "e2e",
"tags": [
"scanner",
"business-error",
"retry-policy"
],
"fixtureSets": [
"fixture.wms.picking"
],
"requiredPermissions": [
"wms.picking.execute"
],
"apiOperations": [
"wms.picking.scan"
],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"playwright-trace",
"api-transcript",
"db-assertions"
]
},
{
"id": "scenario.erp.item-master.lifecycle",
"title": "ERP 품목관리 CRUD·Concurrency·Audit Lifecycle",
"screenId": "ERP-MST-ITEM-001",
"kind": "integration",
"tags": [
"golden-screen",
"master-crud",
"concurrency",
"audit",
"state-policy"
],
"fixtureSets": [
"fixture.erp.item-master-lifecycle"
],
"requiredPermissions": [
"erp.item.read",
"erp.item.write"
],
"apiOperations": [
"erp.items.get",
"erp.items.update",
"erp.items.audit",
"erp.items.deactivate"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"api-transcript",
"db-assertions",
"problem-json",
"screenshot"
]
},
{
"id": "scenario.oms.order-register.lifecycle",
"title": "OMS 주문 작성→확정·읽기전용·Audit Lifecycle",
"screenId": "OMS-ORD-002",
"kind": "e2e",
"tags": [
"golden-screen",
"transaction",
"workflow",
"audit",
"state-policy"
],
"fixtureSets": [
"fixture.oms.order-conflict"
],
"requiredPermissions": [
"oms.order.create",
"oms.order.read",
"oms.order.confirm",
"erp.item.read"
],
"apiOperations": [
"oms.orders.get",
"oms.orders.confirm",
"oms.orders.audit"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"playwright-trace",
"api-transcript",
"db-assertions",
"screenshot"
]
},
{
"id": "scenario.shell.home-navigation-security",
"title": "Home Workbench·권한필터·Scope/Route/Workspace 격리",
"screenId": "OMS-ORD-001",
"kind": "e2e",
"tags": [
"shell",
"home",
"navigation",
"security",
"preference",
"workspace"
],
"fixtureSets": [],
"requiredPermissions": [
"oms.order.read"
],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 11,
"evidence": [
"playwright-trace",
"screenshot",
"local-storage-snapshot"
]
},
{
"id": "scenario.kbx.template-runtime-utility",
"title": "T01~T09 Runtime State·Help/AI/제안 Utility 공통 계약",
"screenId": "OMS-ORD-001",
"kind": "e2e",
"tags": [
"template-contract",
"runtime-state",
"utility",
"accessibility",
"recovery"
],
"fixtureSets": [],
"requiredPermissions": [
"oms.order.read",
"common.ai.use",
"common.suggestion.create"
],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 5,
"evidence": [
"playwright-trace",
"screenshot"
]
},
{
"id": "scenario.common.design-system.form-composition",
"title": "Desktop Form 2-column·Full-span·Responsive 표준 계약",
"screenId": "COMMON-DS-001",
"kind": "e2e",
"tags": [
"template-contract",
"form",
"responsive",
"accessibility",
"design-token"
],
"fixtureSets": [],
"requiredPermissions": [],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 5,
"evidence": [
"playwright-trace",
"screenshot"
]
},
{
"id": "scenario.shell.module-route-recovery",
"title": "Global Module Selector·딥링크 복구·Navigation Capability 보안 계약",
"screenId": "OMS-ORD-001",
"kind": "e2e",
"tags": [
"shell",
"navigation",
"security",
"deep-link",
"accessibility"
],
"fixtureSets": [],
"requiredPermissions": [
"oms.order.read"
],
"apiOperations": [],
"isolation": "ui-only",
"assertionCount": 6,
"evidence": [
"playwright-trace",
"screenshot"
]
},
{
"id": "scenario.erp.item-master.keyboard-recovery",
"title": "ERP 품목 T02 조회·권한·Dirty·Conflict 복구",
"screenId": "ERP-MST-ITEM-001",
"kind": "e2e",
"tags": [
"golden-screen",
"master-crud",
"keyboard",
"permission",
"concurrency",
"audit",
"recovery"
],
"fixtureSets": [
"fixture.erp.item-master-lifecycle"
],
"requiredPermissions": [
"erp.item.read",
"erp.item.write"
],
"apiOperations": [
"erp.items.search",
"erp.items.get"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"playwright-trace",
"screenshot",
"api-transcript",
"db-assertions",
"problem-json"
]
},
{
"id": "scenario.common.operations.queue-recovery",
"title": "업무 예외 T06 Queue 조회·상세 Context·재시도 복구",
"screenId": "COMMON-OPS-001",
"kind": "e2e",
"tags": [
"golden-screen",
"queue",
"exception",
"recovery",
"context-retention",
"permission"
],
"fixtureSets": [
"fixture.common.operations"
],
"requiredPermissions": [
"common.operations.read",
"common.operations.retry"
],
"apiOperations": [
"common.operations.search",
"common.operations.retry"
],
"isolation": "database-reset",
"assertionCount": 5,
"evidence": [
"playwright-trace",
"screenshot",
"api-transcript",
"db-assertions"
]
},
{
"id": "scenario.common.reconcile.mismatch-recovery",
"title": "업무 대사 T07 불일치 필터·비교 Context·복구",
"screenId": "COMMON-REC-001",
"kind": "e2e",
"tags": [
"golden-screen",
"reconcile",
"mismatch-filter",
"eventual-consistency",
"recovery",
"context-retention"
],
"fixtureSets": [
"fixture.common.reconcile"
],
"requiredPermissions": [
"common.reconcile.read"
],
"apiOperations": [
"common.reconcile.search"
],
"isolation": "database-reset",
"assertionCount": 4,
"evidence": [
"playwright-trace",
"screenshot",
"api-transcript",
"db-assertions"
]
}
]
}
File diff suppressed because it is too large Load Diff