@hotmeshio/long-tail 0.10.11 → 0.10.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/escalations/list.d.ts +1 -0
- package/build/api/escalations/list.js +1 -0
- package/build/api/escalations/metadata.d.ts +11 -0
- package/build/api/escalations/metadata.js +27 -7
- package/build/api/scan-codes/config.d.ts +22 -0
- package/build/api/scan-codes/config.js +136 -0
- package/build/api/scan-codes/execute.d.ts +9 -0
- package/build/api/scan-codes/execute.js +372 -0
- package/build/api/scan-codes/index.d.ts +2 -0
- package/build/api/scan-codes/index.js +14 -0
- package/build/lib/db/schemas/026_scan_codes.sql +51 -0
- package/build/lib/db/schemas/027_scan_codes_reindex.sql +23 -0
- package/build/lib/events/system-events.js +4 -0
- package/build/modules/features.d.ts +8 -0
- package/build/modules/features.js +1 -0
- package/build/routes/escalations/list.js +1 -0
- package/build/routes/index.js +2 -0
- package/build/routes/scan-codes.d.ts +2 -0
- package/build/routes/scan-codes.js +138 -0
- package/build/sdk/index.d.ts +4 -0
- package/build/services/escalation/crud.d.ts +1 -1
- package/build/services/escalation/crud.js +4 -2
- package/build/services/escalation/queries.d.ts +1 -0
- package/build/services/escalation/queries.js +2 -0
- package/build/services/escalation/sql.d.ts +11 -6
- package/build/services/escalation/sql.js +20 -20
- package/build/services/scan-code/index.d.ts +4 -0
- package/build/services/scan-code/index.js +21 -0
- package/build/services/scan-code/parse.d.ts +35 -0
- package/build/services/scan-code/parse.js +108 -0
- package/build/services/scan-code/read.d.ts +5 -0
- package/build/services/scan-code/read.js +50 -0
- package/build/services/scan-code/sql.d.ts +10 -0
- package/build/services/scan-code/sql.js +57 -0
- package/build/services/scan-code/validate.d.ts +12 -0
- package/build/services/scan-code/validate.js +78 -0
- package/build/services/scan-code/write.d.ts +26 -0
- package/build/services/scan-code/write.js +71 -0
- package/build/shared/form-validation/index.d.ts +1 -0
- package/build/shared/form-validation/index.js +1 -0
- package/build/shared/form-validation/x-lt-transition.d.ts +47 -0
- package/build/shared/form-validation/x-lt-transition.js +65 -0
- package/build/system/mcp-servers/admin/index.d.ts +1 -0
- package/build/system/mcp-servers/admin/index.js +5 -2
- package/build/system/mcp-servers/admin/scan-codes.d.ts +10 -0
- package/build/system/mcp-servers/admin/scan-codes.js +111 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +232 -14
- package/build/system/mcp-servers/admin/schemas.js +50 -0
- package/build/system/seed/tool-manifests-admin.d.ts +1380 -0
- package/build/system/seed/tool-manifests-admin.js +6 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/events.d.ts +9 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +10 -1
- package/build/types/scan-code.d.ts +183 -0
- package/build/types/scan-code.js +80 -0
- package/build/types/startup.d.ts +6 -0
- package/dashboard/dist/assets/{AdminDashboard-CkTbRfY9.js → AdminDashboard-Bv3pHBzn.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-CkTbRfY9.js.map → AdminDashboard-Bv3pHBzn.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Cm8FRpXi.js → AgentConfigPage-Dk2zlvDb.js} +6 -6
- package/dashboard/dist/assets/{AgentConfigPage-Cm8FRpXi.js.map → AgentConfigPage-Dk2zlvDb.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-sQ1-UT46.js → AgentDetailPage-DUno6EGs.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-sQ1-UT46.js.map → AgentDetailPage-DUno6EGs.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-bSx_mdae.js → AgentsPage-CToVu1qj.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-bSx_mdae.js.map → AgentsPage-CToVu1qj.js.map} +1 -1
- package/dashboard/dist/assets/{AutoGrowTextarea-y-oNY51_.js → AutoGrowTextarea-DgEQeRQw.js} +2 -2
- package/dashboard/dist/assets/{AutoGrowTextarea-y-oNY51_.js.map → AutoGrowTextarea-DgEQeRQw.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-8pMC7Xv6.js → AvailableEscalationsPage-DldboL4W.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-8pMC7Xv6.js.map → AvailableEscalationsPage-DldboL4W.js.map} +1 -1
- package/dashboard/dist/assets/BotPicker-DQOpVB4M.js +2 -0
- package/dashboard/dist/assets/{BotPicker-C4uGH2x9.js.map → BotPicker-DQOpVB4M.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BRoOeKcc.js → CapabilitiesPage-Dmf46PUJ.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BRoOeKcc.js.map → CapabilitiesPage-Dmf46PUJ.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CIj8Adc9.js → CollapsibleSection-CDADefUY.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CIj8Adc9.js.map → CollapsibleSection-CDADefUY.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-Ugi_9Ukq.js → ConfirmDeleteModal-CQsJUzEa.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-Ugi_9Ukq.js.map → ConfirmDeleteModal-CQsJUzEa.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-GUEdiiL5.js → CopyableId-4Lqlc5cU.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-GUEdiiL5.js.map → CopyableId-4Lqlc5cU.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-D3t0XMhE.js → CountdownTimer-DPjIkerB.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-D3t0XMhE.js.map → CountdownTimer-DPjIkerB.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-B73Si6K1.js → CredentialsPage-8LIEvomi.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-B73Si6K1.js.map → CredentialsPage-8LIEvomi.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-Ca1aHolt.js → CronLabel-CK3WSsM5.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-Ca1aHolt.js.map → CronLabel-CK3WSsM5.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-_9E9x1YN.js → CustomDurationPicker-FPmlA6cE.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-_9E9x1YN.js.map → CustomDurationPicker-FPmlA6cE.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-BTu2AaEl.js → DataTable-Bir0Xs1p.js} +2 -2
- package/dashboard/dist/assets/{DataTable-BTu2AaEl.js.map → DataTable-Bir0Xs1p.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-NYn6TWHz.js → DropZone-CL9gA7pu.js} +2 -2
- package/dashboard/dist/assets/{DropZone-NYn6TWHz.js.map → DropZone-CL9gA7pu.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-karxia93.js → ElapsedCell-BZVkVxE0.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-karxia93.js.map → ElapsedCell-BZVkVxE0.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-BcsfPq9T.js → EmptyState-lpUFYfun.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-BcsfPq9T.js.map → EmptyState-lpUFYfun.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CDaNmbUA.js → EscalationListSchemaPage-kYLdUtZX.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CDaNmbUA.js.map → EscalationListSchemaPage-kYLdUtZX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-k-2hFT2t.js → EscalationSchemaPage-kUmCDivo.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-k-2hFT2t.js.map → EscalationSchemaPage-kUmCDivo.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-C1e7IPn_.js → EscalationsOverview-D17auO-m.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-C1e7IPn_.js.map → EscalationsOverview-D17auO-m.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CIrrtL7_.js → EventTable-CwPWl163.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CIrrtL7_.js.map → EventTable-CwPWl163.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-CzjtH74v.js → FilterBar-D7GghUsU.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-CzjtH74v.js.map → FilterBar-D7GghUsU.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-LMpWw8z1.js → GraphInvokePage-D11uOnZi.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-LMpWw8z1.js.map → GraphInvokePage-D11uOnZi.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-Kl2DBG6l.js → HomePage-Bcq10Bxx.js} +2 -2
- package/dashboard/dist/assets/{HomePage-Kl2DBG6l.js.map → HomePage-Bcq10Bxx.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-IPXsTb3Q.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-B2fub0DY.js.map → ListToolbar-IPXsTb3Q.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-odYnCZCC.js → McpOverview-Dx2j0KkF.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-odYnCZCC.js.map → McpOverview-Dx2j0KkF.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BtqwHUAg.js → McpQueryDetailPage-CzF_bna8.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-BtqwHUAg.js.map → McpQueryDetailPage-CzF_bna8.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CPkVwNIK.js → McpQueryPage-CNsuiw_q.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CPkVwNIK.js.map → McpQueryPage-CNsuiw_q.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-D-Rz9MRw.js → McpRunDetailPage-BJguEMS0.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-D-Rz9MRw.js.map → McpRunDetailPage-BJguEMS0.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-rdpZ2yMh.js → McpRunsPage-CK96s3Nt.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-rdpZ2yMh.js.map → McpRunsPage-CK96s3Nt.js.map} +1 -1
- package/dashboard/dist/assets/{Modal-Dr1Xy0j0.js → Modal-BU7No9NH.js} +2 -2
- package/dashboard/dist/assets/{Modal-Dr1Xy0j0.js.map → Modal-BU7No9NH.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-GwO-WfhX.js → NamespacePill-B9Vc_Pz2.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-GwO-WfhX.js.map → NamespacePill-B9Vc_Pz2.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DlyGLPAs.js → OperationsPage-DvWrLuH6.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DlyGLPAs.js.map → OperationsPage-DvWrLuH6.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-Csei5vj-.js → OperatorDashboard-C-jE0IRA.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Csei5vj-.js.map → OperatorDashboard-C-jE0IRA.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Bo9BU9pK.js → PageHeader-Ce4GcIYo.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Bo9BU9pK.js.map → PageHeader-Ce4GcIYo.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-8_5cOSKL.js → PageHeaderWithStats-Ck0KZvXD.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-8_5cOSKL.js.map → PageHeaderWithStats-Ck0KZvXD.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage--ZL6Or6v.js → PersonaDetailPage-CJ6jqo7h.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage--ZL6Or6v.js.map → PersonaDetailPage-CJ6jqo7h.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-Bdcoay3P.js → PersonasPage-D8hL3kL5.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-Bdcoay3P.js.map → PersonasPage-D8hL3kL5.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-CCERr9vQ.js → PriorityBadge-BETdj4M-.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-CCERr9vQ.js.map → PriorityBadge-BETdj4M-.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-HrmVQq7S.js → ProcessDetailPage-Vnx8Z5_y.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-HrmVQq7S.js.map → ProcessDetailPage-Vnx8Z5_y.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-_xmj6Bo-.js → ProcessesListPage-DRYtvS3N.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-_xmj6Bo-.js.map → ProcessesListPage-DRYtvS3N.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-C0ju2-4K.js → RoleDetailPage-BKkUvTO-.js} +3 -3
- package/dashboard/dist/assets/{RoleDetailPage-C0ju2-4K.js.map → RoleDetailPage-BKkUvTO-.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-CQlnEWkK.js → RolePill-CnuBPhPw.js} +2 -2
- package/dashboard/dist/assets/{RolePill-CQlnEWkK.js.map → RolePill-CnuBPhPw.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-CKluVSpB.js → RolesPage-BHzWK9n6.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-CKluVSpB.js.map → RolesPage-BHzWK9n6.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-BA9L9djf.js → RowActions-eYrzgQSj.js} +2 -2
- package/dashboard/dist/assets/{RowActions-BA9L9djf.js.map → RowActions-eYrzgQSj.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-DdfecQ1U.js → RunAsSelector-CS3KQ-BF.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DdfecQ1U.js.map → RunAsSelector-CS3KQ-BF.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-BW4P4zWf.js +2 -0
- package/dashboard/dist/assets/ScanCodesPage-BW4P4zWf.js.map +1 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-BLykA4j-.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-BLykA4j-.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-BBYkevuR.js → ScopeBadge-BUpYpS3x.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-BBYkevuR.js.map → ScopeBadge-BUpYpS3x.js.map} +1 -1
- package/dashboard/dist/assets/{StatCard-Ca-ngCaD.js → StatCard-BXQ8dD9Y.js} +2 -2
- package/dashboard/dist/assets/{StatCard-Ca-ngCaD.js.map → StatCard-BXQ8dD9Y.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BwUvykDo.js → StatusBadge-DkgllZHv.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BwUvykDo.js.map → StatusBadge-DkgllZHv.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-cLddIdtT.js → StickyPagination-hMrnLXde.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-cLddIdtT.js.map → StickyPagination-hMrnLXde.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-CZXWDawC.js → StreamMessageDetail-DyJyZwBl.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-CZXWDawC.js.map → StreamMessageDetail-DyJyZwBl.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-fWY0gaf3.js → SwimlaneTimeline-BlzV74V5.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-fWY0gaf3.js.map → SwimlaneTimeline-BlzV74V5.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-CDKbslLx.js → TagInput-BbZ25nNe.js} +2 -2
- package/dashboard/dist/assets/{TagInput-CDKbslLx.js.map → TagInput-BbZ25nNe.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BjE4G2yn.js → TaskDetailPage-B0p_Z4J_.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BjE4G2yn.js.map → TaskDetailPage-B0p_Z4J_.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-G3RuYRNZ.js → TaskQueuePill-D0QKBrN3.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-G3RuYRNZ.js.map → TaskQueuePill-D0QKBrN3.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-KAhmCWB2.js → TasksListPage-CiGR2QiQ.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-KAhmCWB2.js.map → TasksListPage-CiGR2QiQ.js.map} +1 -1
- package/dashboard/dist/assets/TimeAgo-D_DA9ucC.js +2 -0
- package/dashboard/dist/assets/{TimeAgo-C_H2TyZw.js.map → TimeAgo-D_DA9ucC.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-COG_4Flg.js → TimestampCell-C7rkC9nh.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-COG_4Flg.js.map → TimestampCell-C7rkC9nh.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-ChSyRJZC.js → ToolPill-8xY9rkoc.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-ChSyRJZC.js.map → ToolPill-8xY9rkoc.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BPdJECW0.js → ToolTestPanel-E8efYGYs.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BPdJECW0.js.map → ToolTestPanel-E8efYGYs.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DAqx5JqA.js → TopicDetailPage-B455XrRc.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-DAqx5JqA.js.map → TopicDetailPage-B455XrRc.js.map} +1 -1
- package/dashboard/dist/assets/TopicsPage-1VAc29Qw.js +2 -0
- package/dashboard/dist/assets/{TopicsPage-DoGqAdPm.js.map → TopicsPage-1VAc29Qw.js.map} +1 -1
- package/dashboard/dist/assets/UserName-DikzjQHJ.js +2 -0
- package/dashboard/dist/assets/{UserName-CKO_rk1R.js.map → UserName-DikzjQHJ.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-D3VQ9iQV.js → WorkflowExecutionPage-C15GSAoe.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-D3VQ9iQV.js.map → WorkflowExecutionPage-C15GSAoe.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-CNbwug5p.js → WorkflowPill-Da406nEj.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-CNbwug5p.js.map → WorkflowPill-Da406nEj.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DdJ86We6.js → WorkflowsDashboard-BMQd_0tW.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DdJ86We6.js.map → WorkflowsDashboard-BMQd_0tW.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-ZfFBzePp.js → WorkflowsOverview-CdxjVifp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-ZfFBzePp.js.map → WorkflowsOverview-CdxjVifp.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-4bd5yXdA.js → YamlWorkflowDetailPage-DNVffIXa.js} +13 -13
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-4bd5yXdA.js.map → YamlWorkflowDetailPage-DNVffIXa.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-iHPNXjQj.js → YamlWorkflowsPage-BGP8wuos.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-iHPNXjQj.js.map → YamlWorkflowsPage-BGP8wuos.js.map} +1 -1
- package/dashboard/dist/assets/{agents-DjD5U3Wb.js → agents-BZJLIJ4h.js} +2 -2
- package/dashboard/dist/assets/{agents-DjD5U3Wb.js.map → agents-BZJLIJ4h.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DiljVapH.js → bots-ClLcDGJb.js} +2 -2
- package/dashboard/dist/assets/{bots-DiljVapH.js.map → bots-ClLcDGJb.js.map} +1 -1
- package/dashboard/dist/assets/capabilities-IaCcS7ge.js +2 -0
- package/dashboard/dist/assets/{capabilities-DV_5ghHT.js.map → capabilities-IaCcS7ge.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BKMvfWCB.js → controlplane-Zi4m_MSx.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BKMvfWCB.js.map → controlplane-Zi4m_MSx.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BQpCaJId.js → escalation-columns-BY2mg9DY.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BQpCaJId.js.map → escalation-columns-BY2mg9DY.js.map} +1 -1
- package/dashboard/dist/assets/{index-Tx_ETzcH.js → index-BqGnhkh0.js} +2 -2
- package/dashboard/dist/assets/{index-Tx_ETzcH.js.map → index-BqGnhkh0.js.map} +1 -1
- package/dashboard/dist/assets/index-BzkE48xJ.js +6 -0
- package/dashboard/dist/assets/index-BzkE48xJ.js.map +1 -0
- package/dashboard/dist/assets/{index-CI8rrKjx.js → index-C3o4OisO.js} +2 -2
- package/dashboard/dist/assets/{index-CI8rrKjx.js.map → index-C3o4OisO.js.map} +1 -1
- package/dashboard/dist/assets/{index-BO-7S9Xw.js → index-CJu2PBNx.js} +2 -2
- package/dashboard/dist/assets/{index-BO-7S9Xw.js.map → index-CJu2PBNx.js.map} +1 -1
- package/dashboard/dist/assets/{index-CItsikDw.js → index-CLmZaNTK.js} +2 -2
- package/dashboard/dist/assets/{index-CItsikDw.js.map → index-CLmZaNTK.js.map} +1 -1
- package/dashboard/dist/assets/index-CfAi1OsI.js +65 -0
- package/dashboard/dist/assets/index-CfAi1OsI.js.map +1 -0
- package/dashboard/dist/assets/{index-BaV3l0UE.js → index-CmnNqpWg.js} +2 -2
- package/dashboard/dist/assets/{index-BaV3l0UE.js.map → index-CmnNqpWg.js.map} +1 -1
- package/dashboard/dist/assets/{index-nIrYejxe.js → index-CvNBdkB1.js} +3 -3
- package/dashboard/dist/assets/{index-nIrYejxe.js.map → index-CvNBdkB1.js.map} +1 -1
- package/dashboard/dist/assets/{index-xZqQxqu2.js → index-D0zFReGL.js} +2 -2
- package/dashboard/dist/assets/{index-xZqQxqu2.js.map → index-D0zFReGL.js.map} +1 -1
- package/dashboard/dist/assets/{index-CStR4uIU.js → index-Dldi3Q3M.js} +2 -2
- package/dashboard/dist/assets/{index-CStR4uIU.js.map → index-Dldi3Q3M.js.map} +1 -1
- package/dashboard/dist/assets/{index-DhATO1cS.js → index-kiKZresb.js} +2 -2
- package/dashboard/dist/assets/{index-DhATO1cS.js.map → index-kiKZresb.js.map} +1 -1
- package/dashboard/dist/assets/index-mKcQGi2B.js +3 -0
- package/dashboard/dist/assets/index-mKcQGi2B.js.map +1 -0
- package/dashboard/dist/assets/{index-BsOxMMmb.js → index-yGNt29V9.js} +2 -2
- package/dashboard/dist/assets/{index-BsOxMMmb.js.map → index-yGNt29V9.js.map} +1 -1
- package/dashboard/dist/assets/index-zQiUPfxA.css +1 -0
- package/dashboard/dist/assets/{knowledge-BocTnSiA.js → knowledge-DWLxGTib.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BocTnSiA.js.map → knowledge-DWLxGTib.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-C1KBjKQ_.js → mcp-B6AARZ2I.js} +2 -2
- package/dashboard/dist/assets/{mcp-C1KBjKQ_.js.map → mcp-B6AARZ2I.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-B3cjukkA.js → mcp-query-DrkvBU3a.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-B3cjukkA.js.map → mcp-query-DrkvBU3a.js.map} +1 -1
- package/dashboard/dist/assets/{personas-DiA2bJaX.js → personas-Cmz2SAEU.js} +2 -2
- package/dashboard/dist/assets/{personas-DiA2bJaX.js.map → personas-Cmz2SAEU.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Dt2d2EFR.js → pipelines-CSgfVCMy.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Dt2d2EFR.js.map → pipelines-CSgfVCMy.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-cDh2hNml.js → tasks-UOtUkDk-.js} +2 -2
- package/dashboard/dist/assets/{tasks-cDh2hNml.js.map → tasks-UOtUkDk-.js.map} +1 -1
- package/dashboard/dist/assets/{topics-yFlGF-u1.js → topics-Df5hGh6o.js} +2 -2
- package/dashboard/dist/assets/{topics-yFlGF-u1.js.map → topics-Df5hGh6o.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-BA5S7V54.js → useDebouncedValue-C4P2jQuh.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-BA5S7V54.js.map → useDebouncedValue-C4P2jQuh.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-D2R_ckS8.js → useEventHooks-PDbuSJ12.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-D2R_ckS8.js.map → useEventHooks-PDbuSJ12.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-B7suPsIK.js → useFilterParams-crmlBw_l.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-B7suPsIK.js.map → useFilterParams-crmlBw_l.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-u-V1GVUD.js → useNamespace-tZSOlge3.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-u-V1GVUD.js.map → useNamespace-tZSOlge3.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BhOZeqgE.js → useYamlActivityEvents-CINLzE32.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BhOZeqgE.js.map → useYamlActivityEvents-CINLzE32.js.map} +1 -1
- package/dashboard/dist/assets/{users-BoXPwdee.js → users-G8qwyZKS.js} +2 -2
- package/dashboard/dist/assets/{users-BoXPwdee.js.map → users-G8qwyZKS.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-D71XjkNy.js → vendor-icons-BpZiWH2f.js} +135 -130
- package/dashboard/dist/assets/vendor-icons-BpZiWH2f.js.map +1 -0
- package/dashboard/dist/assets/{vendor-query-B2UbickB.js → vendor-query-RUZdMvN6.js} +2 -2
- package/dashboard/dist/assets/{vendor-query-B2UbickB.js.map → vendor-query-RUZdMvN6.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-react-C1YOyCSV.js → vendor-react-CdqEC2zv.js} +2 -2
- package/dashboard/dist/assets/{vendor-react-C1YOyCSV.js.map → vendor-react-CdqEC2zv.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-mCoyKuLZ.js → workflows-DbPqi1TW.js} +2 -2
- package/dashboard/dist/assets/{workflows-mCoyKuLZ.js.map → workflows-DbPqi1TW.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-CWxXGDpn.js → yaml-workflows-DozD8hpR.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-CWxXGDpn.js.map → yaml-workflows-DozD8hpR.js.map} +1 -1
- package/dashboard/dist/index.html +5 -5
- package/docs/hitl/x-lt-transition.md +105 -0
- package/docs/scan-codes.md +243 -0
- package/package.json +2 -2
- package/dashboard/dist/assets/BotPicker-C4uGH2x9.js +0 -2
- package/dashboard/dist/assets/ListToolbar-B2fub0DY.js +0 -2
- package/dashboard/dist/assets/TimeAgo-C_H2TyZw.js +0 -2
- package/dashboard/dist/assets/TopicsPage-DoGqAdPm.js +0 -2
- package/dashboard/dist/assets/UserName-CKO_rk1R.js +0 -2
- package/dashboard/dist/assets/capabilities-DV_5ghHT.js +0 -2
- package/dashboard/dist/assets/index-B-WkiNRN.js +0 -6
- package/dashboard/dist/assets/index-B-WkiNRN.js.map +0 -1
- package/dashboard/dist/assets/index-DbTD-dio.js +0 -63
- package/dashboard/dist/assets/index-DbTD-dio.js.map +0 -1
- package/dashboard/dist/assets/index-DnlsDaAw.css +0 -1
- package/dashboard/dist/assets/index-kzIIeVbx.js +0 -5
- package/dashboard/dist/assets/index-kzIIeVbx.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-D71XjkNy.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteScanRule = exports.upsertScanRule = exports.getScanRule = exports.listScanRules = exports.deleteScanScheme = exports.upsertScanScheme = exports.getScanScheme = exports.listScanSchemes = exports.executeScanCode = void 0;
|
|
4
|
+
var execute_1 = require("./execute");
|
|
5
|
+
Object.defineProperty(exports, "executeScanCode", { enumerable: true, get: function () { return execute_1.executeScanCode; } });
|
|
6
|
+
var config_1 = require("./config");
|
|
7
|
+
Object.defineProperty(exports, "listScanSchemes", { enumerable: true, get: function () { return config_1.listScanSchemes; } });
|
|
8
|
+
Object.defineProperty(exports, "getScanScheme", { enumerable: true, get: function () { return config_1.getScanScheme; } });
|
|
9
|
+
Object.defineProperty(exports, "upsertScanScheme", { enumerable: true, get: function () { return config_1.upsertScanScheme; } });
|
|
10
|
+
Object.defineProperty(exports, "deleteScanScheme", { enumerable: true, get: function () { return config_1.deleteScanScheme; } });
|
|
11
|
+
Object.defineProperty(exports, "listScanRules", { enumerable: true, get: function () { return config_1.listScanRules; } });
|
|
12
|
+
Object.defineProperty(exports, "getScanRule", { enumerable: true, get: function () { return config_1.getScanRule; } });
|
|
13
|
+
Object.defineProperty(exports, "upsertScanRule", { enumerable: true, get: function () { return config_1.upsertScanRule; } });
|
|
14
|
+
Object.defineProperty(exports, "deleteScanRule", { enumerable: true, get: function () { return config_1.deleteScanRule; } });
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
-- Migration 026: Scan-code schemes and rules
|
|
2
|
+
--
|
|
3
|
+
-- A scan code arrives from a physical input source (barcode scanner, RFID
|
|
4
|
+
-- reader, manual entry) as a plain string encoding version:category:target.
|
|
5
|
+
-- The leading digit (1-9) selects a SCHEME: which escalation metadata facet
|
|
6
|
+
-- the target resolves against and how the string parses (delimited text or
|
|
7
|
+
-- fixed-width digits). The two-digit category selects a RULE: an ordered
|
|
8
|
+
-- list of condition/action steps evaluated against the escalation surface,
|
|
9
|
+
-- plus a fallback screen when no step matches.
|
|
10
|
+
--
|
|
11
|
+
-- Rules are plain config consulted at execute time (like lt_config_workflows);
|
|
12
|
+
-- nothing pins a historical rule, so there is no snapshot table. Provenance
|
|
13
|
+
-- is stamped into escalation metadata by the execute path instead.
|
|
14
|
+
|
|
15
|
+
CREATE TABLE IF NOT EXISTS lt_config_scan_schemes (
|
|
16
|
+
version SMALLINT PRIMARY KEY CHECK (version BETWEEN 1 AND 9),
|
|
17
|
+
name TEXT NOT NULL,
|
|
18
|
+
description TEXT,
|
|
19
|
+
target_facet TEXT NOT NULL,
|
|
20
|
+
encoding TEXT NOT NULL DEFAULT 'fixed'
|
|
21
|
+
CHECK (encoding IN ('fixed', 'delimited')),
|
|
22
|
+
delimiter TEXT NOT NULL DEFAULT ':',
|
|
23
|
+
target_length SMALLINT,
|
|
24
|
+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
25
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
26
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
27
|
+
-- fixed-width parsing needs to know where the target ends
|
|
28
|
+
CONSTRAINT chk_scan_scheme_fixed_length
|
|
29
|
+
CHECK (encoding <> 'fixed' OR target_length IS NOT NULL)
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE OR REPLACE TRIGGER trg_lt_config_scan_schemes_updated_at
|
|
33
|
+
BEFORE UPDATE ON lt_config_scan_schemes
|
|
34
|
+
FOR EACH ROW EXECUTE FUNCTION lt_set_updated_at();
|
|
35
|
+
|
|
36
|
+
CREATE TABLE IF NOT EXISTS lt_config_scan_actions (
|
|
37
|
+
scheme_version SMALLINT NOT NULL
|
|
38
|
+
REFERENCES lt_config_scan_schemes(version) ON DELETE CASCADE,
|
|
39
|
+
category TEXT NOT NULL CHECK (category ~ '^[0-9]{2}$'),
|
|
40
|
+
name TEXT NOT NULL,
|
|
41
|
+
steps JSONB NOT NULL DEFAULT '[]',
|
|
42
|
+
fallback JSONB NOT NULL DEFAULT '{}',
|
|
43
|
+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
44
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
45
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
46
|
+
PRIMARY KEY (scheme_version, category)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
CREATE OR REPLACE TRIGGER trg_lt_config_scan_actions_updated_at
|
|
50
|
+
BEFORE UPDATE ON lt_config_scan_actions
|
|
51
|
+
FOR EACH ROW EXECUTE FUNCTION lt_set_updated_at();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Migration 027: Scan-code numbering inversion
|
|
2
|
+
--
|
|
3
|
+
-- The scheme index moves to the leading TWO digits (10-99) and the category
|
|
4
|
+
-- (rule) index to a single digit (0-9): a code now reads ##:#:target. Two
|
|
5
|
+
-- reasons: a code never starts with a leading zero (some scanners choke on it),
|
|
6
|
+
-- and the top-level "named item" you organize by (the scheme) gets the wider
|
|
7
|
+
-- 90-slot space while each scheme's rules stay a small 0-9 set. The indices are
|
|
8
|
+
-- assigned automatically; operators name entries, never pick numbers.
|
|
9
|
+
--
|
|
10
|
+
-- Old rows (single-digit version, two-digit category) cannot satisfy the new
|
|
11
|
+
-- checks and their codes no longer parse, so the config is cleared and re-seeded.
|
|
12
|
+
|
|
13
|
+
TRUNCATE lt_config_scan_actions, lt_config_scan_schemes;
|
|
14
|
+
|
|
15
|
+
ALTER TABLE lt_config_scan_schemes
|
|
16
|
+
DROP CONSTRAINT IF EXISTS lt_config_scan_schemes_version_check;
|
|
17
|
+
ALTER TABLE lt_config_scan_schemes
|
|
18
|
+
ADD CONSTRAINT lt_config_scan_schemes_version_check CHECK (version BETWEEN 10 AND 99);
|
|
19
|
+
|
|
20
|
+
ALTER TABLE lt_config_scan_actions
|
|
21
|
+
DROP CONSTRAINT IF EXISTS lt_config_scan_actions_category_check;
|
|
22
|
+
ALTER TABLE lt_config_scan_actions
|
|
23
|
+
ADD CONSTRAINT lt_config_scan_actions_category_check CHECK (category ~ '^[0-9]$');
|
|
@@ -44,6 +44,10 @@ function mapSystemEvent(event) {
|
|
|
44
44
|
escalationId: row.id || segments[2],
|
|
45
45
|
originId: row.origin_id || event.origin_id || undefined,
|
|
46
46
|
status: ESCALATION_STATUS_BY_VERB[verb] ?? verb,
|
|
47
|
+
// Assignment provenance rides the SystemEvent envelope, NOT the row (it is
|
|
48
|
+
// not a column). Forward it so a consumer can tell a born-assigned,
|
|
49
|
+
// system-directed hand-off (`claimed` with true) from an interactive claim.
|
|
50
|
+
assignedAtCreation: event.assigned_at_creation,
|
|
47
51
|
data: row,
|
|
48
52
|
timestamp: event.ts,
|
|
49
53
|
};
|
|
@@ -21,6 +21,14 @@ export interface FeatureFlags {
|
|
|
21
21
|
* one-time accounts (e.g. a customer resolving a single form).
|
|
22
22
|
*/
|
|
23
23
|
publicPaceBoard: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Scan-code input on every login: the header scan affordance, the panel,
|
|
26
|
+
* and the global keyboard-wedge capture. Opt-IN: default false — a
|
|
27
|
+
* deployment turns it on with `features.scanCodes: true` when scanners are
|
|
28
|
+
* part of the floor workflow. The scan-code execute/config API stays
|
|
29
|
+
* available either way (the flag gates the dashboard surface).
|
|
30
|
+
*/
|
|
31
|
+
scanCodes: boolean;
|
|
24
32
|
}
|
|
25
33
|
/** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
|
|
26
34
|
export declare function configureFeatureFlags(patch?: Partial<FeatureFlags>): void;
|
|
@@ -5,6 +5,7 @@ exports.getFeatureFlags = getFeatureFlags;
|
|
|
5
5
|
const DEFAULT_FLAGS = {
|
|
6
6
|
dbMaintenance: true,
|
|
7
7
|
publicPaceBoard: true,
|
|
8
|
+
scanCodes: false,
|
|
8
9
|
};
|
|
9
10
|
let flags = { ...DEFAULT_FLAGS };
|
|
10
11
|
/** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
|
|
@@ -92,6 +92,7 @@ function registerListRoutes(router) {
|
|
|
92
92
|
type: req.query.type,
|
|
93
93
|
subtype: req.query.subtype,
|
|
94
94
|
assigned_to: req.query.assigned_to,
|
|
95
|
+
parent_id: req.query.parent_id,
|
|
95
96
|
claimed: req.query.claimed === 'true',
|
|
96
97
|
priority: req.query.priority ? parseInt(req.query.priority, 10) : undefined,
|
|
97
98
|
limit: req.query.limit ? parseInt(req.query.limit, 10) : undefined,
|
package/build/routes/index.js
CHANGED
|
@@ -36,6 +36,7 @@ const agents_1 = __importDefault(require("./agents"));
|
|
|
36
36
|
const capabilities_1 = __importDefault(require("./capabilities"));
|
|
37
37
|
const topics_1 = __importDefault(require("./topics"));
|
|
38
38
|
const nats_credentials_1 = __importDefault(require("./nats-credentials"));
|
|
39
|
+
const scan_codes_1 = __importDefault(require("./scan-codes"));
|
|
39
40
|
const router = (0, express_1.Router)();
|
|
40
41
|
// Public routes (no auth required — they handle their own auth)
|
|
41
42
|
router.use('/auth', auth_2.default);
|
|
@@ -72,6 +73,7 @@ router.use('/knowledge', knowledge_1.default);
|
|
|
72
73
|
router.use('/agents', agents_1.default);
|
|
73
74
|
router.use('/capabilities', capabilities_1.default);
|
|
74
75
|
router.use('/topics', topics_1.default);
|
|
76
|
+
router.use('/scan-codes', scan_codes_1.default);
|
|
75
77
|
const overview_1 = __importDefault(require("./overview"));
|
|
76
78
|
router.use('/overview', overview_1.default);
|
|
77
79
|
const diagnostics_1 = __importDefault(require("./diagnostics"));
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const api = __importStar(require("../api/scan-codes"));
|
|
38
|
+
const auth_1 = require("../modules/auth");
|
|
39
|
+
const router = (0, express_1.Router)();
|
|
40
|
+
// ── Execute ───────────────────────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* POST /api/scan-codes/execute
|
|
43
|
+
* Execute a raw scan code (from any input source) as the calling user.
|
|
44
|
+
* Every terminal state is a structured 200 outcome.
|
|
45
|
+
*/
|
|
46
|
+
router.post('/execute', async (req, res) => {
|
|
47
|
+
const result = await api.executeScanCode({ code: req.body.code }, req.auth);
|
|
48
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
49
|
+
});
|
|
50
|
+
// ── Scheme CRUD (admin, engineer, superadmin) ─────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* GET /api/scan-codes/schemes
|
|
53
|
+
* List all scan schemes.
|
|
54
|
+
*/
|
|
55
|
+
router.get('/schemes', async (_req, res) => {
|
|
56
|
+
const result = await api.listScanSchemes();
|
|
57
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* GET /api/scan-codes/schemes/:version
|
|
61
|
+
* Get one scheme with its rules.
|
|
62
|
+
*/
|
|
63
|
+
router.get('/schemes/:version', async (req, res) => {
|
|
64
|
+
const result = await api.getScanScheme({ version: Number(req.params.version) });
|
|
65
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* PUT /api/scan-codes/schemes/:version
|
|
69
|
+
* Create or replace a scan scheme. Admin, engineer, or superadmin.
|
|
70
|
+
*/
|
|
71
|
+
router.put('/schemes/:version', auth_1.requireRoleManager, async (req, res) => {
|
|
72
|
+
const result = await api.upsertScanScheme({
|
|
73
|
+
version: Number(req.params.version),
|
|
74
|
+
name: req.body.name,
|
|
75
|
+
description: req.body.description,
|
|
76
|
+
target_facet: req.body.target_facet,
|
|
77
|
+
encoding: req.body.encoding,
|
|
78
|
+
delimiter: req.body.delimiter,
|
|
79
|
+
target_length: req.body.target_length,
|
|
80
|
+
enabled: req.body.enabled,
|
|
81
|
+
});
|
|
82
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* DELETE /api/scan-codes/schemes/:version
|
|
86
|
+
* Delete a scheme and its rules (cascade). Admin, engineer, or superadmin.
|
|
87
|
+
*/
|
|
88
|
+
router.delete('/schemes/:version', auth_1.requireRoleManager, async (req, res) => {
|
|
89
|
+
const result = await api.deleteScanScheme({ version: Number(req.params.version) });
|
|
90
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
91
|
+
});
|
|
92
|
+
// ── Rule CRUD (admin, engineer, superadmin) ───────────────────────────────
|
|
93
|
+
/**
|
|
94
|
+
* GET /api/scan-codes/schemes/:version/actions
|
|
95
|
+
* List a scheme's rules.
|
|
96
|
+
*/
|
|
97
|
+
router.get('/schemes/:version/actions', async (req, res) => {
|
|
98
|
+
const result = await api.listScanRules({ version: Number(req.params.version) });
|
|
99
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
100
|
+
});
|
|
101
|
+
/**
|
|
102
|
+
* GET /api/scan-codes/schemes/:version/actions/:category
|
|
103
|
+
* Get one rule.
|
|
104
|
+
*/
|
|
105
|
+
router.get('/schemes/:version/actions/:category', async (req, res) => {
|
|
106
|
+
const result = await api.getScanRule({
|
|
107
|
+
version: Number(req.params.version),
|
|
108
|
+
category: req.params.category,
|
|
109
|
+
});
|
|
110
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
111
|
+
});
|
|
112
|
+
/**
|
|
113
|
+
* PUT /api/scan-codes/schemes/:version/actions/:category
|
|
114
|
+
* Create or replace a rule. Admin, engineer, or superadmin.
|
|
115
|
+
*/
|
|
116
|
+
router.put('/schemes/:version/actions/:category', auth_1.requireRoleManager, async (req, res) => {
|
|
117
|
+
const result = await api.upsertScanRule({
|
|
118
|
+
scheme_version: Number(req.params.version),
|
|
119
|
+
category: req.params.category,
|
|
120
|
+
name: req.body.name,
|
|
121
|
+
steps: req.body.steps,
|
|
122
|
+
fallback: req.body.fallback,
|
|
123
|
+
enabled: req.body.enabled,
|
|
124
|
+
});
|
|
125
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* DELETE /api/scan-codes/schemes/:version/actions/:category
|
|
129
|
+
* Delete a rule. Admin, engineer, or superadmin.
|
|
130
|
+
*/
|
|
131
|
+
router.delete('/schemes/:version/actions/:category', auth_1.requireRoleManager, async (req, res) => {
|
|
132
|
+
const result = await api.deleteScanRule({
|
|
133
|
+
version: Number(req.params.version),
|
|
134
|
+
category: req.params.category,
|
|
135
|
+
});
|
|
136
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
137
|
+
});
|
|
138
|
+
exports.default = router;
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -96,6 +96,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
96
96
|
type?: string;
|
|
97
97
|
subtype?: string;
|
|
98
98
|
assigned_to?: string;
|
|
99
|
+
parent_id?: string;
|
|
99
100
|
claimed?: boolean;
|
|
100
101
|
priority?: number;
|
|
101
102
|
limit?: number;
|
|
@@ -202,6 +203,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
202
203
|
assignee?: string;
|
|
203
204
|
metadata?: Record<string, any>;
|
|
204
205
|
provisionIfAbsent?: import("../api/escalations/helpers").ProvisionIfAbsent;
|
|
206
|
+
restrictRoles?: string[];
|
|
205
207
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
206
208
|
resolveByMetadata: (input: {
|
|
207
209
|
key: string;
|
|
@@ -209,6 +211,8 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
209
211
|
resolverPayload: Record<string, any>;
|
|
210
212
|
assignee?: string;
|
|
211
213
|
metadata?: Record<string, any>;
|
|
214
|
+
restrictRoles?: string[];
|
|
215
|
+
extraFacets?: Record<string, any>;
|
|
212
216
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
213
217
|
searchByFacets: (input: import("..").FacetQuery, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
214
218
|
claimGroups: (input: {
|
|
@@ -241,4 +241,4 @@ export interface ResolveByMetadataResult {
|
|
|
241
241
|
* business logic over the shared table, so it runs as one atomic statement on
|
|
242
242
|
* `hmsh_escalations` rather than through the generic SDK resolve.
|
|
243
243
|
*/
|
|
244
|
-
export declare function resolveByMetadataAtomic(key: string, value: string, userId: string, resolverPayload: Record<string, any>, metadata?: Record<string, any>, writeAllRoles?: string[] | null, writeSelfRoles?: string[] | null, enforcingRoles?: string[] | null, assertId?: string | null): Promise<ResolveByMetadataResult>;
|
|
244
|
+
export declare function resolveByMetadataAtomic(key: string, value: string, userId: string, resolverPayload: Record<string, any>, metadata?: Record<string, any>, writeAllRoles?: string[] | null, writeSelfRoles?: string[] | null, enforcingRoles?: string[] | null, assertId?: string | null, extraFacets?: Record<string, any> | null): Promise<ResolveByMetadataResult>;
|
|
@@ -554,10 +554,12 @@ async function claimByMetadata(key, value, userId, durationMinutes = 30, metadat
|
|
|
554
554
|
* business logic over the shared table, so it runs as one atomic statement on
|
|
555
555
|
* `hmsh_escalations` rather than through the generic SDK resolve.
|
|
556
556
|
*/
|
|
557
|
-
async function resolveByMetadataAtomic(key, value, userId, resolverPayload, metadata, writeAllRoles, writeSelfRoles, enforcingRoles, assertId) {
|
|
557
|
+
async function resolveByMetadataAtomic(key, value, userId, resolverPayload, metadata, writeAllRoles, writeSelfRoles, enforcingRoles, assertId, extraFacets) {
|
|
558
558
|
await (0, client_1.ensureEscalationCompatView)();
|
|
559
559
|
const pool = (0, db_1.getPool)();
|
|
560
|
-
|
|
560
|
+
// The statement's filter is jsonb containment — extra facet guards simply
|
|
561
|
+
// widen the containment object and ride the same atomic WHERE.
|
|
562
|
+
const filter = JSON.stringify({ [key]: value, ...(extraFacets ?? {}) });
|
|
561
563
|
const payloadJson = JSON.stringify(resolverPayload);
|
|
562
564
|
const metaPatch = metadata ? JSON.stringify(metadata) : null;
|
|
563
565
|
// null write_all roles = global (no filter). A scoped caller passes its arrays
|
|
@@ -298,6 +298,8 @@ async function listEscalations(filters) {
|
|
|
298
298
|
};
|
|
299
299
|
if (filters.assigned_to)
|
|
300
300
|
where.assignedTo = filters.assigned_to;
|
|
301
|
+
if (filters.parent_id)
|
|
302
|
+
where.parentId = filters.parent_id;
|
|
301
303
|
if (heldNow)
|
|
302
304
|
where.available = false;
|
|
303
305
|
if (filters.metadata)
|
|
@@ -26,13 +26,18 @@ export declare function searchEscalationsQuery(orderBy: string): string;
|
|
|
26
26
|
* 3. `metadata.signal_id` present, row already claimed and claim not expired →
|
|
27
27
|
* a concurrent caller is handling the signal. `signal_already_claimed = true`;
|
|
28
28
|
* caller returns 409 without re-signaling.
|
|
29
|
-
* 4. `signal_key` present (atomic conditionLT) →
|
|
29
|
+
* 4. `signal_key` present (atomic conditionLT) → the write skips entirely.
|
|
30
30
|
* Caller invokes SDK resolve to atomically mark resolved + deliver the signal.
|
|
31
31
|
*
|
|
32
|
-
* Signal_id hardening: the
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
32
|
+
* Signal_id hardening: the write runs for signal_id rows too, stamping
|
|
33
|
+
* `assigned_to` inside the FOR UPDATE transaction so a concurrent second caller
|
|
34
|
+
* sees `signal_already_claimed = true` and aborts. The resolve columns skip
|
|
35
|
+
* signal_id rows (CASE branches) — the workflow resolves durably.
|
|
36
|
+
*
|
|
37
|
+
* ONE UPDATE does both claim and resolve: Postgres does not support a second
|
|
38
|
+
* same-statement UPDATE of a row already updated by an earlier CTE (the second
|
|
39
|
+
* silently no-ops), so a chained claim→resolve pair leaves the row claimed but
|
|
40
|
+
* pending. The resolve columns ride the claim UPDATE as CASE branches instead.
|
|
36
41
|
*
|
|
37
42
|
* $1 = metadata filter (jsonb), $2 = userId, $3 = resolver_payload (jsonb),
|
|
38
43
|
* $4 = metadata patch (jsonb, nullable), $5 = write_all roles (text[], null = global /
|
|
@@ -53,7 +58,7 @@ export declare function searchEscalationsQuery(orderBy: string): string;
|
|
|
53
58
|
* resolution surfaces as zero rows → the caller's conflict handling). This is
|
|
54
59
|
* the same pick-then-guarded-finish shape the signal outcomes already use.
|
|
55
60
|
*/
|
|
56
|
-
export declare const RESOLVE_BY_METADATA_ATOMIC = "WITH target AS MATERIALIZED (\n SELECT *\n FROM public.hmsh_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (\n $5::text[] IS NULL\n OR role = ANY($5)\n OR (role = ANY($6::text[]) AND assigned_to = $2)\n )\n AND ($8::uuid IS NULL OR id = $8::uuid)\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE\n),\
|
|
61
|
+
export declare const RESOLVE_BY_METADATA_ATOMIC = "WITH target AS MATERIALIZED (\n SELECT *\n FROM public.hmsh_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (\n $5::text[] IS NULL\n OR role = ANY($5)\n OR (role = ANY($6::text[]) AND assigned_to = $2)\n )\n AND ($8::uuid IS NULL OR id = $8::uuid)\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE\n),\nwritten AS (\n UPDATE public.hmsh_escalations e\n SET assigned_to = COALESCE(e.assigned_to, $2),\n claimed_at = COALESCE(e.claimed_at, NOW()),\n assigned_until = CASE\n WHEN e.assigned_to IS NOT NULL AND e.assigned_until > NOW() THEN e.assigned_until\n ELSE NOW() + INTERVAL '5 minutes' END,\n claim_expires_at = CASE\n WHEN e.assigned_to IS NOT NULL AND e.assigned_until > NOW() THEN e.claim_expires_at\n ELSE NOW() + INTERVAL '5 minutes' END,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END,\n status = CASE WHEN (target.metadata->>'signal_id') IS NULL\n THEN 'resolved' ELSE e.status END,\n resolved_at = CASE WHEN (target.metadata->>'signal_id') IS NULL\n THEN NOW() ELSE e.resolved_at END,\n resolver_payload = CASE WHEN (target.metadata->>'signal_id') IS NULL\n THEN $3 ELSE e.resolver_payload END,\n updated_at = NOW()\n FROM target\n WHERE e.id = target.id\n AND target.signal_key IS NULL\n AND ($7::text[] IS NULL OR NOT (target.role = ANY($7)))\n RETURNING e.*\n)\nSELECT\n written.*,\n target.id AS target_id,\n target.role AS target_role,\n target.metadata AS target_metadata,\n target.envelope AS target_envelope,\n target.escalation_payload AS target_escalation_payload,\n target.metadata->>'signal_id' AS signal_id,\n target.signal_key AS signal_key,\n target.workflow_id AS target_workflow_id,\n target.workflow_type AS target_workflow_type,\n target.task_queue AS target_task_queue,\n (target.assigned_to IS NOT NULL\n AND target.assigned_until IS NOT NULL\n AND target.assigned_until > NOW()) AS signal_already_claimed,\n CASE\n WHEN written.status = 'resolved' THEN 'resolved'\n WHEN $7::text[] IS NOT NULL AND target.role = ANY($7) THEN 'validation_required'\n ELSE 'signal_required'\n END AS outcome\nFROM target\nLEFT JOIN written ON written.id = target.id";
|
|
57
62
|
/**
|
|
58
63
|
* Live counts — pending, active claims, and priority (past-threshold) per role.
|
|
59
64
|
*
|
|
@@ -108,13 +108,18 @@ function searchEscalationsQuery(orderBy) {
|
|
|
108
108
|
* 3. `metadata.signal_id` present, row already claimed and claim not expired →
|
|
109
109
|
* a concurrent caller is handling the signal. `signal_already_claimed = true`;
|
|
110
110
|
* caller returns 409 without re-signaling.
|
|
111
|
-
* 4. `signal_key` present (atomic conditionLT) →
|
|
111
|
+
* 4. `signal_key` present (atomic conditionLT) → the write skips entirely.
|
|
112
112
|
* Caller invokes SDK resolve to atomically mark resolved + deliver the signal.
|
|
113
113
|
*
|
|
114
|
-
* Signal_id hardening: the
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
114
|
+
* Signal_id hardening: the write runs for signal_id rows too, stamping
|
|
115
|
+
* `assigned_to` inside the FOR UPDATE transaction so a concurrent second caller
|
|
116
|
+
* sees `signal_already_claimed = true` and aborts. The resolve columns skip
|
|
117
|
+
* signal_id rows (CASE branches) — the workflow resolves durably.
|
|
118
|
+
*
|
|
119
|
+
* ONE UPDATE does both claim and resolve: Postgres does not support a second
|
|
120
|
+
* same-statement UPDATE of a row already updated by an earlier CTE (the second
|
|
121
|
+
* silently no-ops), so a chained claim→resolve pair leaves the row claimed but
|
|
122
|
+
* pending. The resolve columns ride the claim UPDATE as CASE branches instead.
|
|
118
123
|
*
|
|
119
124
|
* $1 = metadata filter (jsonb), $2 = userId, $3 = resolver_payload (jsonb),
|
|
120
125
|
* $4 = metadata patch (jsonb, nullable), $5 = write_all roles (text[], null = global /
|
|
@@ -151,7 +156,7 @@ WITH target AS MATERIALIZED (
|
|
|
151
156
|
LIMIT 1
|
|
152
157
|
FOR UPDATE
|
|
153
158
|
),
|
|
154
|
-
|
|
159
|
+
written AS (
|
|
155
160
|
UPDATE public.hmsh_escalations e
|
|
156
161
|
SET assigned_to = COALESCE(e.assigned_to, $2),
|
|
157
162
|
claimed_at = COALESCE(e.claimed_at, NOW()),
|
|
@@ -164,26 +169,21 @@ claimed AS (
|
|
|
164
169
|
metadata = CASE WHEN $4::jsonb IS NOT NULL
|
|
165
170
|
THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb
|
|
166
171
|
ELSE e.metadata END,
|
|
172
|
+
status = CASE WHEN (target.metadata->>'signal_id') IS NULL
|
|
173
|
+
THEN 'resolved' ELSE e.status END,
|
|
174
|
+
resolved_at = CASE WHEN (target.metadata->>'signal_id') IS NULL
|
|
175
|
+
THEN NOW() ELSE e.resolved_at END,
|
|
176
|
+
resolver_payload = CASE WHEN (target.metadata->>'signal_id') IS NULL
|
|
177
|
+
THEN $3 ELSE e.resolver_payload END,
|
|
167
178
|
updated_at = NOW()
|
|
168
179
|
FROM target
|
|
169
180
|
WHERE e.id = target.id
|
|
170
181
|
AND target.signal_key IS NULL
|
|
171
182
|
AND ($7::text[] IS NULL OR NOT (target.role = ANY($7)))
|
|
172
183
|
RETURNING e.*
|
|
173
|
-
),
|
|
174
|
-
resolved AS (
|
|
175
|
-
UPDATE public.hmsh_escalations e
|
|
176
|
-
SET status = 'resolved',
|
|
177
|
-
resolved_at = NOW(),
|
|
178
|
-
resolver_payload = $3,
|
|
179
|
-
updated_at = NOW()
|
|
180
|
-
FROM claimed
|
|
181
|
-
WHERE e.id = claimed.id
|
|
182
|
-
AND (claimed.metadata->>'signal_id') IS NULL
|
|
183
|
-
RETURNING e.*
|
|
184
184
|
)
|
|
185
185
|
SELECT
|
|
186
|
-
|
|
186
|
+
written.*,
|
|
187
187
|
target.id AS target_id,
|
|
188
188
|
target.role AS target_role,
|
|
189
189
|
target.metadata AS target_metadata,
|
|
@@ -198,12 +198,12 @@ SELECT
|
|
|
198
198
|
AND target.assigned_until IS NOT NULL
|
|
199
199
|
AND target.assigned_until > NOW()) AS signal_already_claimed,
|
|
200
200
|
CASE
|
|
201
|
-
WHEN
|
|
201
|
+
WHEN written.status = 'resolved' THEN 'resolved'
|
|
202
202
|
WHEN $7::text[] IS NOT NULL AND target.role = ANY($7) THEN 'validation_required'
|
|
203
203
|
ELSE 'signal_required'
|
|
204
204
|
END AS outcome
|
|
205
205
|
FROM target
|
|
206
|
-
LEFT JOIN
|
|
206
|
+
LEFT JOIN written ON written.id = target.id`;
|
|
207
207
|
// ---------------------------------------------------------------------------
|
|
208
208
|
// Station metrics — split into two queries with very different cost profiles.
|
|
209
209
|
//
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { listScanSchemes, getScanScheme, listScanRules, getScanRule, } from './read';
|
|
2
|
+
export { upsertScanScheme, deleteScanScheme, upsertScanRule, deleteScanRule, seedScanScheme, seedScanRule, type ScanSchemeInput, type ScanRuleInput, } from './write';
|
|
3
|
+
export { parseScanCode, interpolateScanTemplate, type ScanParseResult, type ScanParseFailure, type ScanTemplateContext, } from './parse';
|
|
4
|
+
export { assertValidScheme, assertValidSteps } from './validate';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertValidSteps = exports.assertValidScheme = exports.interpolateScanTemplate = exports.parseScanCode = exports.seedScanRule = exports.seedScanScheme = exports.deleteScanRule = exports.upsertScanRule = exports.deleteScanScheme = exports.upsertScanScheme = exports.getScanRule = exports.listScanRules = exports.getScanScheme = exports.listScanSchemes = void 0;
|
|
4
|
+
var read_1 = require("./read");
|
|
5
|
+
Object.defineProperty(exports, "listScanSchemes", { enumerable: true, get: function () { return read_1.listScanSchemes; } });
|
|
6
|
+
Object.defineProperty(exports, "getScanScheme", { enumerable: true, get: function () { return read_1.getScanScheme; } });
|
|
7
|
+
Object.defineProperty(exports, "listScanRules", { enumerable: true, get: function () { return read_1.listScanRules; } });
|
|
8
|
+
Object.defineProperty(exports, "getScanRule", { enumerable: true, get: function () { return read_1.getScanRule; } });
|
|
9
|
+
var write_1 = require("./write");
|
|
10
|
+
Object.defineProperty(exports, "upsertScanScheme", { enumerable: true, get: function () { return write_1.upsertScanScheme; } });
|
|
11
|
+
Object.defineProperty(exports, "deleteScanScheme", { enumerable: true, get: function () { return write_1.deleteScanScheme; } });
|
|
12
|
+
Object.defineProperty(exports, "upsertScanRule", { enumerable: true, get: function () { return write_1.upsertScanRule; } });
|
|
13
|
+
Object.defineProperty(exports, "deleteScanRule", { enumerable: true, get: function () { return write_1.deleteScanRule; } });
|
|
14
|
+
Object.defineProperty(exports, "seedScanScheme", { enumerable: true, get: function () { return write_1.seedScanScheme; } });
|
|
15
|
+
Object.defineProperty(exports, "seedScanRule", { enumerable: true, get: function () { return write_1.seedScanRule; } });
|
|
16
|
+
var parse_1 = require("./parse");
|
|
17
|
+
Object.defineProperty(exports, "parseScanCode", { enumerable: true, get: function () { return parse_1.parseScanCode; } });
|
|
18
|
+
Object.defineProperty(exports, "interpolateScanTemplate", { enumerable: true, get: function () { return parse_1.interpolateScanTemplate; } });
|
|
19
|
+
var validate_1 = require("./validate");
|
|
20
|
+
Object.defineProperty(exports, "assertValidScheme", { enumerable: true, get: function () { return validate_1.assertValidScheme; } });
|
|
21
|
+
Object.defineProperty(exports, "assertValidSteps", { enumerable: true, get: function () { return validate_1.assertValidSteps; } });
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ParsedScanCode, type ScanScheme } from '../../types';
|
|
2
|
+
export interface ScanParseFailure {
|
|
3
|
+
/** Why the code did not parse. */
|
|
4
|
+
reason: 'empty' | 'unknown_version' | 'scheme_disabled' | 'malformed';
|
|
5
|
+
detail: string;
|
|
6
|
+
}
|
|
7
|
+
export type ScanParseResult = {
|
|
8
|
+
ok: true;
|
|
9
|
+
parsed: ParsedScanCode;
|
|
10
|
+
scheme: ScanScheme;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
failure: ScanParseFailure;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Parse a raw scan string against the configured schemes. Pure — no I/O.
|
|
17
|
+
*
|
|
18
|
+
* The leading TWO digits pick the scheme (10-99, so a code never starts with a
|
|
19
|
+
* leading zero); the scheme then defines how the remainder splits into a
|
|
20
|
+
* single-digit category (0-9) and the target:
|
|
21
|
+
* - delimited: `10:1:ABC-123` (delimiter from the scheme row)
|
|
22
|
+
* - fixed: `1017554332` (one category digit, then target_length digits)
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseScanCode(raw: string, schemes: ScanScheme[]): ScanParseResult;
|
|
25
|
+
export interface ScanTemplateContext {
|
|
26
|
+
target: string;
|
|
27
|
+
category: string;
|
|
28
|
+
scannedAt: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Replace SCAN_TEMPLATE_TOKENS inside string values of a params object.
|
|
32
|
+
* Deep, pure, non-mutating. Only exact-token and in-string replacement of
|
|
33
|
+
* the three known tokens — no expression language.
|
|
34
|
+
*/
|
|
35
|
+
export declare function interpolateScanTemplate<T>(value: T, ctx: ScanTemplateContext): T;
|