@hotmeshio/long-tail 0.25.0 → 0.25.2
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/batch-flag.d.ts +19 -0
- package/build/api/escalations/batch-flag.js +138 -0
- package/build/api/escalations/index.d.ts +2 -0
- package/build/api/escalations/index.js +8 -1
- package/build/api/escalations/roster-action.d.ts +37 -0
- package/build/api/escalations/roster-action.js +179 -0
- package/build/api/scan-codes/choice-roles.d.ts +3 -0
- package/build/api/scan-codes/choice-roles.js +48 -0
- package/build/api/scan-codes/choice.js +8 -0
- package/build/api/scan-codes/fill-labels.d.ts +15 -0
- package/build/api/scan-codes/fill-labels.js +99 -0
- package/build/api/scan-codes/hold.js +1 -0
- package/build/api/scan-codes/present.js +7 -2
- package/build/api/scan-codes/verb-fill.js +22 -5
- package/build/routes/escalations/resolve.js +45 -0
- package/build/sdk/index.d.ts +11 -0
- package/build/sdk/index.js +3 -0
- package/build/services/domain/seed.d.ts +12 -10
- package/build/services/domain/seed.js +31 -25
- package/build/services/escalation/batch-flag.d.ts +25 -0
- package/build/services/escalation/batch-flag.js +51 -0
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +1 -0
- package/build/services/escalation/roster.d.ts +3 -1
- package/build/services/escalation/roster.js +6 -1
- package/build/services/scan-code/validate-subject.js +16 -0
- package/build/services/scan-code/validate.js +7 -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-actions.d.ts +80 -0
- package/build/shared/form-validation/x-lt-actions.js +133 -0
- package/build/shared/form-validation/x-lt-roster.d.ts +2 -0
- package/build/shared/form-validation/x-lt-roster.js +50 -6
- package/build/start/workers.d.ts +3 -0
- package/build/start/workers.js +15 -5
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +19 -0
- package/build/types/escalation.js +4 -0
- package/build/types/index.d.ts +1 -1
- package/build/types/scan-choice.d.ts +9 -0
- package/build/types/scan-code/response.d.ts +2 -0
- package/build/types/scan-code/rule.d.ts +17 -0
- package/build/types/startup.d.ts +8 -1
- package/dashboard/dist/assets/{AdminDashboard-DWVRAu63.js → AdminDashboard-B8MqNLiB.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DWVRAu63.js.map → AdminDashboard-B8MqNLiB.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Exjtjbvp.js → AgentConfigPage-Yg81Eiuo.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-Exjtjbvp.js.map → AgentConfigPage-Yg81Eiuo.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-nDbZo6RB.js → AgentDetailPage-ZUGYEONO.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-nDbZo6RB.js.map → AgentDetailPage-ZUGYEONO.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-Dsk9iHps.js → AgentsPage-CZIWMwak.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-Dsk9iHps.js.map → AgentsPage-CZIWMwak.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-BVtpc4xO.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-D1mCqj8Z.js.map → AvailableEscalationsPage-BVtpc4xO.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-u5760MWZ.js → BotPicker-8bf0yOCT.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-u5760MWZ.js.map → BotPicker-8bf0yOCT.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-CtISXXmW.js → BulkAssignModal-B2lr1J6P.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-CtISXXmW.js.map → BulkAssignModal-B2lr1J6P.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BKIlrQfU.js → CapabilitiesPage-BQQBR2sj.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BKIlrQfU.js.map → CapabilitiesPage-BQQBR2sj.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DlBVTFqc.js → CollapsibleSection-DFW8TYyU.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DlBVTFqc.js.map → CollapsibleSection-DFW8TYyU.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-Pabkchg_.js → ConfirmDeleteModal-DGlOlQAo.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-Pabkchg_.js.map → ConfirmDeleteModal-DGlOlQAo.js.map} +1 -1
- package/dashboard/dist/assets/{ConnectedAppsPage-DG2YZGN3.js → ConnectedAppsPage-CIM9gzHj.js} +2 -2
- package/dashboard/dist/assets/{ConnectedAppsPage-DG2YZGN3.js.map → ConnectedAppsPage-CIM9gzHj.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-5t8S2qMi.js → CountdownTimer-BD_iWm6S.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-5t8S2qMi.js.map → CountdownTimer-BD_iWm6S.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-CPVbYQow.js → CredentialsPage-CTtUkvoD.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CPVbYQow.js.map → CredentialsPage-CTtUkvoD.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-C7UbTrO-.js → CronLabel-rZMptkYQ.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-C7UbTrO-.js.map → CronLabel-rZMptkYQ.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-DCZpORx-.js → DropZone-u1JGfR9G.js} +2 -2
- package/dashboard/dist/assets/{DropZone-DCZpORx-.js.map → DropZone-u1JGfR9G.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-Yz7-LbtE.js → ElapsedCell-CmK9gHC5.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-Yz7-LbtE.js.map → ElapsedCell-CmK9gHC5.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-xgPRdKEq.js → EntityTimelinePanel-Cfg0EMZs.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-xgPRdKEq.js.map → EntityTimelinePanel-Cfg0EMZs.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CqCd-y6B.js → EscalationListSchemaPage-CPcbC1-9.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CqCd-y6B.js.map → EscalationListSchemaPage-CPcbC1-9.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-D8YVQNph.js → EscalationSchemaPage-BsYdNVN7.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-D8YVQNph.js.map → EscalationSchemaPage-BsYdNVN7.js.map} +1 -1
- package/dashboard/dist/assets/EscalationTimeline-D1enxZDs.js +2 -0
- package/dashboard/dist/assets/{EscalationTimeline-D6jrDcBb.js.map → EscalationTimeline-D1enxZDs.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-CGGT-QTu.js → EscalationTitleSelect-DwqhnPKX.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-CGGT-QTu.js.map → EscalationTitleSelect-DwqhnPKX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-B7O4ttP4.js → EscalationsOverview-ChuKh02E.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-B7O4ttP4.js.map → EscalationsOverview-ChuKh02E.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DJniXnhe.js → EventTable-GqZIKPce.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DJniXnhe.js.map → EventTable-GqZIKPce.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-f-LEKcHI.js → FilterBar-CqPFZkVU.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-f-LEKcHI.js.map → FilterBar-CqPFZkVU.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-CR0MtYv8.js → GraphInvokePage-_fB7mtBU.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-CR0MtYv8.js.map → GraphInvokePage-_fB7mtBU.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-HVw7T5ER.js → HomePage-BXA0Cz0F.js} +2 -2
- package/dashboard/dist/assets/{HomePage-HVw7T5ER.js.map → HomePage-BXA0Cz0F.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-CTGK5BXW.js → ListToolbar-Bf4DFITI.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-CTGK5BXW.js.map → ListToolbar-Bf4DFITI.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-B2bbKKu2.js → McpOverview-H61XQRji.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-B2bbKKu2.js.map → McpOverview-H61XQRji.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DgLxwwJy.js → McpQueryDetailPage-wbwK8WWq.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DgLxwwJy.js.map → McpQueryDetailPage-wbwK8WWq.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CSkczeJP.js → McpQueryPage-CYvVEk3G.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CSkczeJP.js.map → McpQueryPage-CYvVEk3G.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CrUsDPRD.js → McpRunDetailPage-TZBX68i4.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CrUsDPRD.js.map → McpRunDetailPage-TZBX68i4.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-twxFdTtJ.js → McpRunsPage-Cu91Mh52.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-twxFdTtJ.js.map → McpRunsPage-Cu91Mh52.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-CSZT2fA4.js → NamespacePill-C5epAgq6.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-CSZT2fA4.js.map → NamespacePill-C5epAgq6.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-gOVMrL_a.js → OperationsPage-D-6sKw6y.js} +3 -3
- package/dashboard/dist/assets/{OperationsPage-gOVMrL_a.js.map → OperationsPage-D-6sKw6y.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-DD8JUU3L.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-BoeZIyup.js.map → OperatorDashboard-DD8JUU3L.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-C4z1ExF7.js → PageHeader-BSWIspNB.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-C4z1ExF7.js.map → PageHeader-BSWIspNB.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-B_f_Sz_Q.js → PageHeaderWithStats-DDjopQ-k.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-B_f_Sz_Q.js.map → PageHeaderWithStats-DDjopQ-k.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-CDktk1mi.js → PersonaDetailPage-CGri6okV.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-CDktk1mi.js.map → PersonaDetailPage-CGri6okV.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-Bs097x07.js → PersonasPage-DtHW6-Qx.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-Bs097x07.js.map → PersonasPage-DtHW6-Qx.js.map} +1 -1
- package/dashboard/dist/assets/PortalPage-Dgbk_mzr.js +2 -0
- package/dashboard/dist/assets/{PortalPage-DjfjerpF.js.map → PortalPage-Dgbk_mzr.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-B30RatjD.js → ProcessDetailPage-BdkacBrD.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-B30RatjD.js.map → ProcessDetailPage-BdkacBrD.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DrvjzgWT.js → ProcessesListPage-DO5A-OfZ.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DrvjzgWT.js.map → ProcessesListPage-DO5A-OfZ.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-CqGE5lf-.js +8 -0
- package/dashboard/dist/assets/ResolverForm-CqGE5lf-.js.map +1 -0
- package/dashboard/dist/assets/{RoleDetailPage-ClYgn-3d.js → RoleDetailPage-DgVp0Hih.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-ClYgn-3d.js.map → RoleDetailPage-DgVp0Hih.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-Bw_n7EpR.js → RolePill-CoETDpjF.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Bw_n7EpR.js.map → RolePill-CoETDpjF.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-B_3qWsvQ.js → RolesPage-BmsWq83e.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-B_3qWsvQ.js.map → RolesPage-BmsWq83e.js.map} +1 -1
- package/dashboard/dist/assets/RosterWidget-DR-T4Izu.js +2 -0
- package/dashboard/dist/assets/RosterWidget-DR-T4Izu.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-CbJT50Hp.js → RunAsSelector-CyUWGp5P.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-CbJT50Hp.js.map → RunAsSelector-CyUWGp5P.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-CIIDuh8w.js → ScanCodesPage-Cy05JOt4.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-CIIDuh8w.js.map → ScanCodesPage-Cy05JOt4.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-Bd3P3eyh.js → ScanSchemeDetailPage-BX1afzOg.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-Bd3P3eyh.js.map → ScanSchemeDetailPage-BX1afzOg.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-DLAB41tb.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-DLAB41tb.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-CKgfwTy3.js → ScopeBadge-CGsTtqFr.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-CKgfwTy3.js.map → ScopeBadge-CGsTtqFr.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BNOuYZ1m.js → StickyPagination-BzUTnYYE.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BNOuYZ1m.js.map → StickyPagination-BzUTnYYE.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-ALVUnfF1.js → StreamMessageDetail-D0W1ekgG.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-ALVUnfF1.js.map → StreamMessageDetail-D0W1ekgG.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-B5b8-xqI.js → SwimlaneTimeline-BPBwmwuO.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-B5b8-xqI.js.map → SwimlaneTimeline-BPBwmwuO.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-B6fMAqxd.js → TagInput-S7UuVT_M.js} +2 -2
- package/dashboard/dist/assets/{TagInput-B6fMAqxd.js.map → TagInput-S7UuVT_M.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CoV3WcTA.js → TaskDetailPage-VuaIXISy.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CoV3WcTA.js.map → TaskDetailPage-VuaIXISy.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BnDp_DE6.js → TaskQueuePill-BlHNpYiZ.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BnDp_DE6.js.map → TaskQueuePill-BlHNpYiZ.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CkMmOYOE.js → TasksListPage-KaUSoqos.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CkMmOYOE.js.map → TasksListPage-KaUSoqos.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-DVkFgECX.js → TimeAgo-C_E6u0fr.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-DVkFgECX.js.map → TimeAgo-C_E6u0fr.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CfTc6Txy.js → TimestampCell-CUJiAmax.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CfTc6Txy.js.map → TimestampCell-CUJiAmax.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-BRZWo4l8.js → ToolPill-D40uLM_v.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-BRZWo4l8.js.map → ToolPill-D40uLM_v.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-kvqZqM0A.js → ToolTestPanel-Ch5nQANh.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-kvqZqM0A.js.map → ToolTestPanel-Ch5nQANh.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-CjkAAyy8.js → TopicDetailPage-BprToO7w.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-CjkAAyy8.js.map → TopicDetailPage-BprToO7w.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-CJZnv50y.js → TopicsPage-8SmCnQ-E.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-CJZnv50y.js.map → TopicsPage-8SmCnQ-E.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CPJPZnN1.js → UserName-BkJryunF.js} +2 -2
- package/dashboard/dist/assets/{UserName-CPJPZnN1.js.map → UserName-BkJryunF.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-46UV5pJd.js → WorkflowExecutionPage-B2S5ODie.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-46UV5pJd.js.map → WorkflowExecutionPage-B2S5ODie.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-Cly9Ln_3.js → WorkflowPill-DJLcK_CM.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Cly9Ln_3.js.map → WorkflowPill-DJLcK_CM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DtxYdQbQ.js → WorkflowsDashboard-CABuRCXp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DtxYdQbQ.js.map → WorkflowsDashboard-CABuRCXp.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Cg4LSfck.js → WorkflowsOverview-BPUHAj8T.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Cg4LSfck.js.map → WorkflowsOverview-BPUHAj8T.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Del-RCgi.js → YamlWorkflowDetailPage-DZGjT-Tl.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Del-RCgi.js.map → YamlWorkflowDetailPage-DZGjT-Tl.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BF6Jtx24.js → YamlWorkflowsPage-DIxHURlM.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BF6Jtx24.js.map → YamlWorkflowsPage-DIxHURlM.js.map} +1 -1
- package/dashboard/dist/assets/{agents-wL-3dMOX.js → agents-BnDp2rcb.js} +2 -2
- package/dashboard/dist/assets/{agents-wL-3dMOX.js.map → agents-BnDp2rcb.js.map} +1 -1
- package/dashboard/dist/assets/{bots-D72EsztP.js → bots-maURYoyr.js} +2 -2
- package/dashboard/dist/assets/{bots-D72EsztP.js.map → bots-maURYoyr.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DXFo6bRb.js → capabilities-5-TakMUh.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DXFo6bRb.js.map → capabilities-5-TakMUh.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-gQdOgVtH.js → controlplane-BXVVTWoh.js} +2 -2
- package/dashboard/dist/assets/{controlplane-gQdOgVtH.js.map → controlplane-BXVVTWoh.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-v8gx8wFb.js +2 -0
- package/dashboard/dist/assets/{escalation-columns-CSE5wfWQ.js.map → escalation-columns-v8gx8wFb.js.map} +1 -1
- package/dashboard/dist/assets/escalation-items-OWntjDaH.js +2 -0
- package/dashboard/dist/assets/escalation-items-OWntjDaH.js.map +1 -0
- package/dashboard/dist/assets/{index-Btm8FtTQ.js → index-BIfY4mR2.js} +2 -2
- package/dashboard/dist/assets/{index-Btm8FtTQ.js.map → index-BIfY4mR2.js.map} +1 -1
- package/dashboard/dist/assets/{index-h1Useskt.js → index-BTm3-qwq.js} +2 -2
- package/dashboard/dist/assets/{index-h1Useskt.js.map → index-BTm3-qwq.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cu0xdX2t.js → index-CR9rhAvN.js} +2 -2
- package/dashboard/dist/assets/{index-Cu0xdX2t.js.map → index-CR9rhAvN.js.map} +1 -1
- package/dashboard/dist/assets/index-CWKs10VQ.js +13 -0
- package/dashboard/dist/assets/{index-D1lfq5iZ.js.map → index-CWKs10VQ.js.map} +1 -1
- package/dashboard/dist/assets/index-CvKegIVe.js +3 -0
- package/dashboard/dist/assets/index-CvKegIVe.js.map +1 -0
- package/dashboard/dist/assets/{index-BaCDL5fh.js → index-D7peGNN0.js} +27 -27
- package/dashboard/dist/assets/index-D7peGNN0.js.map +1 -0
- package/dashboard/dist/assets/{index-CptTEhWp.js → index-D_ojXTgO.js} +2 -2
- package/dashboard/dist/assets/{index-CptTEhWp.js.map → index-D_ojXTgO.js.map} +1 -1
- package/dashboard/dist/assets/index-Dafrbwk_.js +2 -0
- package/dashboard/dist/assets/{index-BvH8T-jb.js.map → index-Dafrbwk_.js.map} +1 -1
- package/dashboard/dist/assets/{index-czgLyfSo.js → index-Dk7nwVpm.js} +2 -2
- package/dashboard/dist/assets/{index-czgLyfSo.js.map → index-Dk7nwVpm.js.map} +1 -1
- package/dashboard/dist/assets/{index-CDxOQ84B.js → index-DvkcyTE2.js} +2 -2
- package/dashboard/dist/assets/{index-CDxOQ84B.js.map → index-DvkcyTE2.js.map} +1 -1
- package/dashboard/dist/assets/{index-C1iuZ4Q5.js → index-WPVpyoD3.js} +2 -2
- package/dashboard/dist/assets/{index-C1iuZ4Q5.js.map → index-WPVpyoD3.js.map} +1 -1
- package/dashboard/dist/assets/{index-C-QQ5rKF.js → index-YGTGxcTF.js} +2 -2
- package/dashboard/dist/assets/{index-C-QQ5rKF.js.map → index-YGTGxcTF.js.map} +1 -1
- package/dashboard/dist/assets/{index-ujGmmwl6.js → index-vgHzaGmW.js} +2 -2
- package/dashboard/dist/assets/{index-ujGmmwl6.js.map → index-vgHzaGmW.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-150lsM68.js → knowledge-L_zY1zmy.js} +2 -2
- package/dashboard/dist/assets/{knowledge-150lsM68.js.map → knowledge-L_zY1zmy.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CDsSMaYq.js → mcp-query-CFbGudkb.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CDsSMaYq.js.map → mcp-query-CFbGudkb.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-CRtY4v5W.js → mcp-wCWFRA0T.js} +2 -2
- package/dashboard/dist/assets/{mcp-CRtY4v5W.js.map → mcp-wCWFRA0T.js.map} +1 -1
- package/dashboard/dist/assets/{personas-C2Wm4ng1.js → personas-B_VIacZJ.js} +2 -2
- package/dashboard/dist/assets/{personas-C2Wm4ng1.js.map → personas-B_VIacZJ.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-BH0F9-jf.js → pipelines-Bv0Z8xQA.js} +2 -2
- package/dashboard/dist/assets/{pipelines-BH0F9-jf.js.map → pipelines-Bv0Z8xQA.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BkUVpaOa.js → tasks-DP6yaNZs.js} +2 -2
- package/dashboard/dist/assets/{tasks-BkUVpaOa.js.map → tasks-DP6yaNZs.js.map} +1 -1
- package/dashboard/dist/assets/{topics-Crl8HKHq.js → topics-UBSIcpSR.js} +2 -2
- package/dashboard/dist/assets/{topics-Crl8HKHq.js.map → topics-UBSIcpSR.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-Dk3r5xo-.js → useDebouncedValue-R62q3Xpx.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Dk3r5xo-.js.map → useDebouncedValue-R62q3Xpx.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-BXuyHKAs.js → useNamespace-CAaszJDE.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-BXuyHKAs.js.map → useNamespace-CAaszJDE.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DSlkjQfb.js → useYamlActivityEvents-emCp9U69.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DSlkjQfb.js.map → useYamlActivityEvents-emCp9U69.js.map} +1 -1
- package/dashboard/dist/assets/validate-C7yskdEn.js +2 -0
- package/dashboard/dist/assets/validate-C7yskdEn.js.map +1 -0
- package/dashboard/dist/assets/{vendor-icons-C_DQEeBy.js → vendor-icons-DUYcKTjP.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-C_DQEeBy.js.map → vendor-icons-DUYcKTjP.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-B230v5Za.js → yaml-workflows-C2sOwz1p.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-B230v5Za.js.map → yaml-workflows-C2sOwz1p.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/accumulator.md +1 -1
- package/docs/api/http/escalations.md +33 -0
- package/docs/api/sdk/escalations.md +26 -1
- package/docs/code-owned-configuration.md +2 -2
- package/docs/domain-dictionary.md +19 -3
- package/docs/faceted-routing.md +4 -3
- package/docs/hitl/escalation.md +9 -0
- package/docs/hitl/x-lt-display.md +1 -1
- package/docs/hitl/x-lt-embed.md +2 -0
- package/docs/hitl/x-lt-roster.md +32 -8
- package/docs/scan-codes.md +45 -3
- package/package.json +2 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-D1mCqj8Z.js +0 -2
- package/dashboard/dist/assets/EscalationTimeline-D6jrDcBb.js +0 -2
- package/dashboard/dist/assets/FormattedValue-CUtv1g3k.js +0 -2
- package/dashboard/dist/assets/FormattedValue-CUtv1g3k.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-BoeZIyup.js +0 -2
- package/dashboard/dist/assets/PortalPage-DjfjerpF.js +0 -2
- package/dashboard/dist/assets/ResolverForm-Bl8Pibyz.js +0 -8
- package/dashboard/dist/assets/ResolverForm-Bl8Pibyz.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-BiO34nov.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-BiO34nov.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-CSE5wfWQ.js +0 -2
- package/dashboard/dist/assets/escalation-items-BIgBWbaw.js +0 -2
- package/dashboard/dist/assets/escalation-items-BIgBWbaw.js.map +0 -1
- package/dashboard/dist/assets/index-BaCDL5fh.js.map +0 -1
- package/dashboard/dist/assets/index-BvH8T-jb.js +0 -2
- package/dashboard/dist/assets/index-CED9cLE2.js +0 -3
- package/dashboard/dist/assets/index-CED9cLE2.js.map +0 -1
- package/dashboard/dist/assets/index-D1lfq5iZ.js +0 -13
|
@@ -40,6 +40,7 @@ const resolve_batch_1 = require("../escalations/resolve-batch");
|
|
|
40
40
|
const escalation_1 = require("../../types/escalation");
|
|
41
41
|
const types_1 = require("../../types");
|
|
42
42
|
const context_1 = require("./context");
|
|
43
|
+
const fill_labels_1 = require("./fill-labels");
|
|
43
44
|
const grant_1 = require("./grant");
|
|
44
45
|
const locate_1 = require("./locate");
|
|
45
46
|
const subject_1 = require("./subject");
|
|
@@ -60,6 +61,18 @@ function codeOf(key, separator) {
|
|
|
60
61
|
function keysFor(keys, target, separator) {
|
|
61
62
|
return keys.filter((k) => codeOf(k, separator) === target);
|
|
62
63
|
}
|
|
64
|
+
/** Labeled pending entries read as one line; labels may carry commas. */
|
|
65
|
+
const LABEL_JOIN = '; ';
|
|
66
|
+
/** The `{fill.pending}` and `{fill.next}` values for the open keys. */
|
|
67
|
+
function pendingCopy(pending, separator, labeler) {
|
|
68
|
+
const code = (key) => codeOf(key, separator);
|
|
69
|
+
if (!labeler) {
|
|
70
|
+
const codes = [...new Set(pending.map(code))];
|
|
71
|
+
return { pending: codes, ...(codes.length ? { next: codes[0] } : {}) };
|
|
72
|
+
}
|
|
73
|
+
const labels = (0, fill_labels_1.pendingLabels)(pending, code, labeler);
|
|
74
|
+
return { pending: labels.join(LABEL_JOIN), ...(labels.length ? { next: labels[0] } : {}) };
|
|
75
|
+
}
|
|
63
76
|
function progress(batch, filledNow) {
|
|
64
77
|
const remaining = Math.max(0, batch.pending.length - filledNow);
|
|
65
78
|
return { filled: batch.keys.length - remaining, total: batch.keys.length, remaining };
|
|
@@ -82,10 +95,12 @@ async function fillStep(step, ctx) {
|
|
|
82
95
|
if (!batch)
|
|
83
96
|
return (0, context_1.conflict)('the held row is not a batch');
|
|
84
97
|
// 2. Which open slot this scan fills, or why none
|
|
98
|
+
const labeler = (0, fill_labels_1.entryLabeler)(options, row, ctx.scheme);
|
|
99
|
+
const open = pendingCopy(batch.pending, separator, labeler);
|
|
85
100
|
const tpl = {
|
|
86
101
|
...(0, context_1.templateContext)(ctx),
|
|
87
102
|
fill: {
|
|
88
|
-
|
|
103
|
+
...open,
|
|
89
104
|
total: batch.keys.length,
|
|
90
105
|
filled: batch.keys.length - batch.pending.length,
|
|
91
106
|
},
|
|
@@ -96,9 +111,10 @@ async function fillStep(step, ctx) {
|
|
|
96
111
|
const markdown = declared.length
|
|
97
112
|
? `All ${declared.length} of these are already checked off.`
|
|
98
113
|
: scanCodeService.renderScanCopy(step.refuse?.markdown ?? STOCK_UNEXPECTED, tpl);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
const codes = [...new Set(batch.pending.map((k) => codeOf(k, separator)))];
|
|
115
|
+
const expected = labeler
|
|
116
|
+
? (0, fill_labels_1.pendingLabels)(batch.pending, (k) => codeOf(k, separator), labeler)
|
|
117
|
+
: codes.map((code) => (0, fill_labels_1.printedCode)(code, ctx.scheme));
|
|
102
118
|
return (0, context_1.refused)(markdown, {
|
|
103
119
|
refusal: { markdown, expected },
|
|
104
120
|
progress: progress(batch, 0),
|
|
@@ -125,6 +141,7 @@ async function fillStep(step, ctx) {
|
|
|
125
141
|
const data = result.data;
|
|
126
142
|
const done = data.outcome === 'completed';
|
|
127
143
|
const filled = progress(batch, batch.pending.length - (done ? 0 : (data.remaining ?? 0)));
|
|
144
|
+
const next = pendingCopy(batch.pending.filter((k) => k !== itemKey), separator, labeler).next;
|
|
128
145
|
return (0, context_1.withDone)({
|
|
129
146
|
status: 200,
|
|
130
147
|
data: {
|
|
@@ -134,7 +151,7 @@ async function fillStep(step, ctx) {
|
|
|
134
151
|
progress: filled,
|
|
135
152
|
...(done ? { clearSubject: true } : {}),
|
|
136
153
|
},
|
|
137
|
-
}, step, { ...tpl, fill: { ...tpl.fill, ...filled } });
|
|
154
|
+
}, step, { ...tpl, fill: { ...tpl.fill, ...filled, next } });
|
|
138
155
|
}
|
|
139
156
|
const outcome = result.data?.outcome;
|
|
140
157
|
if (outcome === 'duplicate-item')
|
|
@@ -126,6 +126,51 @@ function registerResolveRoutes(router) {
|
|
|
126
126
|
}, auth);
|
|
127
127
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
128
128
|
});
|
|
129
|
+
/**
|
|
130
|
+
* POST /api/escalations/:id/flag-batch-item
|
|
131
|
+
* Flag ONE pending key of a batch escalation (e.g. `Missing`). The key stays
|
|
132
|
+
* pending and still fills; a wait declared with `wakeOnFlag` ends on the flag.
|
|
133
|
+
* Body: { itemKey: string, label: string, payload?: Record<string, any> }
|
|
134
|
+
*/
|
|
135
|
+
router.post('/:id/flag-batch-item', async (req, res) => {
|
|
136
|
+
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
137
|
+
if (!auth)
|
|
138
|
+
return;
|
|
139
|
+
const result = await api.flagBatchItem({ id: req.params.id, itemKey: req.body?.itemKey, label: req.body?.label, payload: req.body?.payload }, auth);
|
|
140
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
141
|
+
});
|
|
142
|
+
/**
|
|
143
|
+
* POST /api/escalations/:id/unflag-batch-item
|
|
144
|
+
* Clear ONE key's flag while the batch escalation is pending.
|
|
145
|
+
* Body: { itemKey: string }
|
|
146
|
+
*/
|
|
147
|
+
router.post('/:id/unflag-batch-item', async (req, res) => {
|
|
148
|
+
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
149
|
+
if (!auth)
|
|
150
|
+
return;
|
|
151
|
+
const result = await api.unflagBatchItem({ id: req.params.id, itemKey: req.body?.itemKey }, auth);
|
|
152
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
153
|
+
});
|
|
154
|
+
/**
|
|
155
|
+
* POST /api/escalations/:id/roster-action
|
|
156
|
+
* Run one action a roster entry offers on this row's form. The server
|
|
157
|
+
* re-reads the action from the row's form schema, checks the entry and any
|
|
158
|
+
* role limit, and runs the act as the person acting: the badged person when
|
|
159
|
+
* X-LT-Acting-Token rides the request (spent only when the act runs).
|
|
160
|
+
* Body: { field: string, action: number, entry: string, code?: string }
|
|
161
|
+
*/
|
|
162
|
+
router.post('/:id/roster-action', async (req, res) => {
|
|
163
|
+
const token = req.headers[acting_1.ACTING_TOKEN_HEADER];
|
|
164
|
+
const result = await api.runRosterAction({
|
|
165
|
+
id: req.params.id,
|
|
166
|
+
field: req.body?.field,
|
|
167
|
+
action: req.body?.action,
|
|
168
|
+
entry: req.body?.entry,
|
|
169
|
+
code: req.body?.code,
|
|
170
|
+
actingToken: typeof token === 'string' && token ? token : undefined,
|
|
171
|
+
}, req.auth);
|
|
172
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
173
|
+
});
|
|
129
174
|
/**
|
|
130
175
|
* POST /api/escalations/:id/resolve
|
|
131
176
|
* Resolve a pending escalation with a human-provided payload. Routes by
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -247,6 +247,17 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
247
247
|
metadata?: Record<string, any>;
|
|
248
248
|
restrictRoles?: string[];
|
|
249
249
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
250
|
+
flagBatchItem: (input: {
|
|
251
|
+
id: string;
|
|
252
|
+
itemKey: string;
|
|
253
|
+
label: string;
|
|
254
|
+
payload?: Record<string, any>;
|
|
255
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
256
|
+
unflagBatchItem: (input: {
|
|
257
|
+
id: string;
|
|
258
|
+
itemKey: string;
|
|
259
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
260
|
+
runRosterAction: (input: import("../api/escalations/roster-action").RosterActionInput, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
250
261
|
accumulate: (input: {
|
|
251
262
|
id: string;
|
|
252
263
|
} & import("../api/escalations/accumulate").AccumulateItemInput, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
package/build/sdk/index.js
CHANGED
|
@@ -146,6 +146,9 @@ function createClient(options = {}) {
|
|
|
146
146
|
resolveBatchItem: bindAuth(escalationsApi.resolveBatchItem, auth),
|
|
147
147
|
resolveBatchItemBySignalKey: bindAuth(escalationsApi.resolveBatchItemBySignalKey, auth),
|
|
148
148
|
resolveBatchItemByMetadata: bindAuth(escalationsApi.resolveBatchItemByMetadata, auth),
|
|
149
|
+
flagBatchItem: bindAuth(escalationsApi.flagBatchItem, auth),
|
|
150
|
+
unflagBatchItem: bindAuth(escalationsApi.unflagBatchItem, auth),
|
|
151
|
+
runRosterAction: bindAuth(escalationsApi.runRosterAction, auth),
|
|
149
152
|
// Open accumulation: add and remove held items, read the ordered collection.
|
|
150
153
|
accumulate: bindAuth(escalationsApi.accumulateItem, auth),
|
|
151
154
|
accumulateBySignalKey: bindAuth(escalationsApi.accumulateItemBySignalKey, auth),
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
import type { DomainDictionary } from '../../types';
|
|
1
2
|
/**
|
|
2
|
-
* Seed the domain dictionary
|
|
3
|
+
* Seed the domain dictionary declared by the host: inline in the start
|
|
4
|
+
* config, or in a JSON file named by path.
|
|
3
5
|
*
|
|
4
6
|
* Default (db-owned): the same insert-if-absent + drift-log contract as
|
|
5
|
-
* seedWorkflowConfig/seedMcpServer
|
|
6
|
-
* row is never overwritten, and a name/version mismatch against the
|
|
7
|
-
* one drift warning.
|
|
7
|
+
* seedWorkflowConfig/seedMcpServer: the DB row is runtime truth, an existing
|
|
8
|
+
* row is never overwritten, and a name/version mismatch against the declared
|
|
9
|
+
* document logs one drift warning.
|
|
8
10
|
*
|
|
9
|
-
* With `apply` (code-owned): the
|
|
10
|
-
* as parsed values; a changed document is written through the same
|
|
11
|
-
* PUT path uses, advancing the row's version counter exactly once.
|
|
12
|
-
* identical document is a no-op.
|
|
11
|
+
* With `apply` (code-owned): the declared document is compared against the
|
|
12
|
+
* stored one as parsed values; a changed document is written through the same
|
|
13
|
+
* upsert the PUT path uses, advancing the row's version counter exactly once.
|
|
14
|
+
* An identical document is a no-op.
|
|
13
15
|
*
|
|
14
16
|
* WARN-ONLY validation: hosts commonly seed roles after long-tail boots, so
|
|
15
17
|
* unknown references log warnings here (the PUT path enforces them hard).
|
|
16
|
-
* Never throws
|
|
18
|
+
* Never throws: a missing or malformed file must not brick boot.
|
|
17
19
|
*/
|
|
18
|
-
export declare function seedDomainDictionary(
|
|
20
|
+
export declare function seedDomainDictionary(source: string | DomainDictionary, apply?: boolean): Promise<void>;
|
|
@@ -14,38 +14,27 @@ const write_1 = require("./write");
|
|
|
14
14
|
const read_1 = require("./read");
|
|
15
15
|
const sql_1 = require("./sql");
|
|
16
16
|
/**
|
|
17
|
-
* Seed the domain dictionary
|
|
17
|
+
* Seed the domain dictionary declared by the host: inline in the start
|
|
18
|
+
* config, or in a JSON file named by path.
|
|
18
19
|
*
|
|
19
20
|
* Default (db-owned): the same insert-if-absent + drift-log contract as
|
|
20
|
-
* seedWorkflowConfig/seedMcpServer
|
|
21
|
-
* row is never overwritten, and a name/version mismatch against the
|
|
22
|
-
* one drift warning.
|
|
21
|
+
* seedWorkflowConfig/seedMcpServer: the DB row is runtime truth, an existing
|
|
22
|
+
* row is never overwritten, and a name/version mismatch against the declared
|
|
23
|
+
* document logs one drift warning.
|
|
23
24
|
*
|
|
24
|
-
* With `apply` (code-owned): the
|
|
25
|
-
* as parsed values; a changed document is written through the same
|
|
26
|
-
* PUT path uses, advancing the row's version counter exactly once.
|
|
27
|
-
* identical document is a no-op.
|
|
25
|
+
* With `apply` (code-owned): the declared document is compared against the
|
|
26
|
+
* stored one as parsed values; a changed document is written through the same
|
|
27
|
+
* upsert the PUT path uses, advancing the row's version counter exactly once.
|
|
28
|
+
* An identical document is a no-op.
|
|
28
29
|
*
|
|
29
30
|
* WARN-ONLY validation: hosts commonly seed roles after long-tail boots, so
|
|
30
31
|
* unknown references log warnings here (the PUT path enforces them hard).
|
|
31
|
-
* Never throws
|
|
32
|
+
* Never throws: a missing or malformed file must not brick boot.
|
|
32
33
|
*/
|
|
33
|
-
async function seedDomainDictionary(
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
: path_1.default.join(process.cwd(), dictionaryPath);
|
|
37
|
-
let dictionary;
|
|
38
|
-
try {
|
|
39
|
-
if (!(0, fs_1.existsSync)(resolved)) {
|
|
40
|
-
logger_1.loggerRegistry.warn(`[lt-domain] domainDictionaryPath not found: ${resolved}`);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
dictionary = JSON.parse((0, fs_1.readFileSync)(resolved, 'utf-8'));
|
|
44
|
-
}
|
|
45
|
-
catch (err) {
|
|
46
|
-
logger_1.loggerRegistry.warn(`[lt-domain] dictionary file unreadable (${resolved}): ${err.message}`);
|
|
34
|
+
async function seedDomainDictionary(source, apply = false) {
|
|
35
|
+
const dictionary = typeof source === 'string' ? readDictionaryFile(source) : source;
|
|
36
|
+
if (!dictionary)
|
|
47
37
|
return;
|
|
48
|
-
}
|
|
49
38
|
try {
|
|
50
39
|
const registry = await (0, write_1.snapshotRegistries)();
|
|
51
40
|
const { errors, warnings, dictionary: derived } = (0, validate_1.validateDictionary)(dictionary, registry);
|
|
@@ -75,10 +64,27 @@ async function seedDomainDictionary(dictionaryPath, apply = false) {
|
|
|
75
64
|
// Row already existed — drift check on name/version only (no deep diff).
|
|
76
65
|
if (doc && (doc.name !== dictionary.name || doc.version !== dictionary.version)) {
|
|
77
66
|
logger_1.loggerRegistry.warn(`[lt-domain] dictionary drift: DB holds "${doc.name}" v${doc.version}, ` +
|
|
78
|
-
`
|
|
67
|
+
`start config declares "${dictionary.name}" v${dictionary.version}; DB is runtime truth`);
|
|
79
68
|
}
|
|
80
69
|
}
|
|
81
70
|
catch (err) {
|
|
82
71
|
logger_1.loggerRegistry.warn(`[lt-domain] dictionary seed failed: ${err.message}`);
|
|
83
72
|
}
|
|
84
73
|
}
|
|
74
|
+
/** The dictionary in a JSON file, resolved against the host cwd; null (logged) when missing or unreadable. */
|
|
75
|
+
function readDictionaryFile(dictionaryPath) {
|
|
76
|
+
const resolved = path_1.default.isAbsolute(dictionaryPath)
|
|
77
|
+
? dictionaryPath
|
|
78
|
+
: path_1.default.join(process.cwd(), dictionaryPath);
|
|
79
|
+
try {
|
|
80
|
+
if (!(0, fs_1.existsSync)(resolved)) {
|
|
81
|
+
logger_1.loggerRegistry.warn(`[lt-domain] domainDictionaryPath not found: ${resolved}`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return JSON.parse((0, fs_1.readFileSync)(resolved, 'utf-8'));
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
logger_1.loggerRegistry.warn(`[lt-domain] dictionary file unreadable (${resolved}): ${err.message}`);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FlagBatchItemOutcome, LTEscalationRecord, UnflagBatchItemOutcome } from '../../types';
|
|
2
|
+
export interface FlagBatchItemInput {
|
|
3
|
+
label: string;
|
|
4
|
+
payload?: Record<string, any>;
|
|
5
|
+
actor?: string;
|
|
6
|
+
metadata?: Record<string, any>;
|
|
7
|
+
resolvedBy?: {
|
|
8
|
+
id: string;
|
|
9
|
+
email?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface BatchFlagOutcome<O extends string> {
|
|
13
|
+
outcome: O;
|
|
14
|
+
/** The post-write row; null on every failure outcome. */
|
|
15
|
+
escalation: LTEscalationRecord | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Flag one pending key of a batch escalation in a single SDK statement. The
|
|
19
|
+
* key stays pending. A row whose wait declared `wakeOnFlag` resolves in the
|
|
20
|
+
* same statement and its workflow wakes; that publishes `escalation.resolved`,
|
|
21
|
+
* any other flag `escalation.updated`. Failures publish nothing.
|
|
22
|
+
*/
|
|
23
|
+
export declare function flagBatchItem(id: string, itemKey: string, input: FlagBatchItemInput): Promise<BatchFlagOutcome<FlagBatchItemOutcome>>;
|
|
24
|
+
/** Clear one key's flag while the row is pending; publishes `escalation.updated`. */
|
|
25
|
+
export declare function unflagBatchItem(id: string, itemKey: string): Promise<BatchFlagOutcome<UnflagBatchItemOutcome>>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.flagBatchItem = flagBatchItem;
|
|
4
|
+
exports.unflagBatchItem = unflagBatchItem;
|
|
5
|
+
const escalation_wire_1 = require("../../lib/events/escalation-wire");
|
|
6
|
+
const uuid_1 = require("../../lib/uuid");
|
|
7
|
+
const client_1 = require("./client");
|
|
8
|
+
const crud_1 = require("./crud");
|
|
9
|
+
const map_1 = require("./map");
|
|
10
|
+
/**
|
|
11
|
+
* Flag one pending key of a batch escalation in a single SDK statement. The
|
|
12
|
+
* key stays pending. A row whose wait declared `wakeOnFlag` resolves in the
|
|
13
|
+
* same statement and its workflow wakes; that publishes `escalation.resolved`,
|
|
14
|
+
* any other flag `escalation.updated`. Failures publish nothing.
|
|
15
|
+
*/
|
|
16
|
+
async function flagBatchItem(id, itemKey, input) {
|
|
17
|
+
if (!(0, uuid_1.isUuid)(id))
|
|
18
|
+
return { outcome: 'not-found', escalation: null };
|
|
19
|
+
const client = await (0, client_1.escalations)();
|
|
20
|
+
const result = await client.flagBatchItem({ id, itemKey, ...input });
|
|
21
|
+
if (!result.ok)
|
|
22
|
+
return { outcome: result.outcome, escalation: null };
|
|
23
|
+
const escalation = (0, map_1.toEscalationRecord)(result.entry);
|
|
24
|
+
publishFlagChange(escalation, itemKey, result.outcome === 'completed');
|
|
25
|
+
return { outcome: result.outcome, escalation };
|
|
26
|
+
}
|
|
27
|
+
/** Clear one key's flag while the row is pending; publishes `escalation.updated`. */
|
|
28
|
+
async function unflagBatchItem(id, itemKey) {
|
|
29
|
+
if (!(0, uuid_1.isUuid)(id))
|
|
30
|
+
return { outcome: 'not-found', escalation: null };
|
|
31
|
+
const client = await (0, client_1.escalations)();
|
|
32
|
+
const result = await client.unflagBatchItem({ id, itemKey });
|
|
33
|
+
if (!result.ok)
|
|
34
|
+
return { outcome: result.outcome, escalation: null };
|
|
35
|
+
const escalation = (0, map_1.toEscalationRecord)(result.entry);
|
|
36
|
+
publishFlagChange(escalation, itemKey, false);
|
|
37
|
+
return { outcome: result.outcome, escalation };
|
|
38
|
+
}
|
|
39
|
+
function publishFlagChange(escalation, itemKey, completed) {
|
|
40
|
+
(0, crud_1.publishEscalationChange)({
|
|
41
|
+
type: completed ? 'escalation.resolved' : 'escalation.updated',
|
|
42
|
+
source: 'service',
|
|
43
|
+
workflowId: escalation.workflow_id || '',
|
|
44
|
+
workflowName: escalation.workflow_type || '',
|
|
45
|
+
taskQueue: escalation.task_queue || '',
|
|
46
|
+
escalationId: escalation.id,
|
|
47
|
+
role: escalation.role,
|
|
48
|
+
status: completed ? 'resolved' : 'pending',
|
|
49
|
+
data: (0, escalation_wire_1.escalationEventData)(escalation, { item_key: itemKey }),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -20,6 +20,7 @@ __exportStar(require("./crud"), exports);
|
|
|
20
20
|
var claim_asserted_1 = require("./claim-asserted");
|
|
21
21
|
Object.defineProperty(exports, "claimAssertedByMetadata", { enumerable: true, get: function () { return claim_asserted_1.claimAssertedByMetadata; } });
|
|
22
22
|
__exportStar(require("./batch"), exports);
|
|
23
|
+
__exportStar(require("./batch-flag"), exports);
|
|
23
24
|
__exportStar(require("./accumulate"), exports);
|
|
24
25
|
__exportStar(require("./bulk"), exports);
|
|
25
26
|
__exportStar(require("./queries"), exports);
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* Member rows are read with `global: true`: a resolver who cannot see a
|
|
9
9
|
* member must never be told the roster is complete.
|
|
10
10
|
*/
|
|
11
|
-
import { type RosterCounts, type ShowIfContext } from '../../shared/form-validation';
|
|
11
|
+
import { type RosterCounts, type RosterDef, type RosterResult, type ShowIfContext } from '../../shared/form-validation';
|
|
12
12
|
/** Each roster field's counts, keyed by field name; empty when the schema declares none. */
|
|
13
13
|
export declare function loadRosterCounts(schema: Record<string, unknown> | null | undefined, ctx: ShowIfContext): Promise<Record<string, RosterCounts>>;
|
|
14
|
+
/** One roster's entries and counts, read the way the widget reads them. */
|
|
15
|
+
export declare function loadRoster(def: RosterDef, ctx: ShowIfContext): Promise<RosterResult>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadRosterCounts = loadRosterCounts;
|
|
4
|
+
exports.loadRoster = loadRoster;
|
|
4
5
|
/**
|
|
5
6
|
* Server-side roster counts: the API-first counterpart of the dashboard's
|
|
6
7
|
* roster widget. For each `x-lt-roster` field of a form schema, the member
|
|
@@ -18,10 +19,14 @@ async function loadRosterCounts(schema, ctx) {
|
|
|
18
19
|
const defs = (0, form_validation_1.readRosterDefs)(schema);
|
|
19
20
|
const counts = {};
|
|
20
21
|
for (const [field, def] of Object.entries(defs)) {
|
|
21
|
-
counts[field] = (
|
|
22
|
+
counts[field] = (await loadRoster(def, ctx)).counts;
|
|
22
23
|
}
|
|
23
24
|
return counts;
|
|
24
25
|
}
|
|
26
|
+
/** One roster's entries and counts, read the way the widget reads them. */
|
|
27
|
+
async function loadRoster(def, ctx) {
|
|
28
|
+
return (0, form_validation_1.computeRoster)(def, ctx, await readMemberRows(def, ctx));
|
|
29
|
+
}
|
|
25
30
|
async function readMemberRows(def, ctx) {
|
|
26
31
|
const query = (0, form_validation_1.rosterQueryOf)(def);
|
|
27
32
|
const scoped = query ? (0, form_validation_1.resolveRosterQuery)(query, ctx) : null;
|
|
@@ -10,6 +10,10 @@ function isSchemeList(value) {
|
|
|
10
10
|
function isStringList(value) {
|
|
11
11
|
return Array.isArray(value) && value.length > 0 && value.every((v) => typeof v === 'string' && v);
|
|
12
12
|
}
|
|
13
|
+
/** A form field name, as `hold.show` names one. */
|
|
14
|
+
const HOLD_SHOW_FIELD = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
15
|
+
/** A fill's label map lives on the batch row: `envelope.<path>` or `metadata.<path>`. */
|
|
16
|
+
const FILL_LABELS_PATH = /^(envelope|metadata)\.[A-Za-z0-9_.-]+$/;
|
|
13
17
|
function isPlainObject(value) {
|
|
14
18
|
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
15
19
|
}
|
|
@@ -165,6 +169,9 @@ function assertValidHold(step, at) {
|
|
|
165
169
|
throw new Error(`${at}: params.hold.expect.prompt must be markdown`);
|
|
166
170
|
}
|
|
167
171
|
}
|
|
172
|
+
if (hold.show !== undefined && (typeof hold.show !== 'string' || !HOLD_SHOW_FIELD.test(hold.show))) {
|
|
173
|
+
throw new Error(`${at}: params.hold.show must name a roster field of the held row's form`);
|
|
174
|
+
}
|
|
168
175
|
}
|
|
169
176
|
function assertValidFill(step, at) {
|
|
170
177
|
const fill = step.params?.fill;
|
|
@@ -180,6 +187,15 @@ function assertValidFill(step, at) {
|
|
|
180
187
|
if (fill.payload !== undefined && !isPlainObject(fill.payload)) {
|
|
181
188
|
throw new Error(`${at}: params.fill.payload must be an object`);
|
|
182
189
|
}
|
|
190
|
+
if (fill.labels !== undefined && (typeof fill.labels !== 'string' || !FILL_LABELS_PATH.test(fill.labels))) {
|
|
191
|
+
throw new Error(`${at}: params.fill.labels must name a map on the row, e.g. "envelope.labels"`);
|
|
192
|
+
}
|
|
193
|
+
if (fill.label !== undefined && (typeof fill.label !== 'string' || !fill.label.trim())) {
|
|
194
|
+
throw new Error(`${at}: params.fill.label must be a non-empty template`);
|
|
195
|
+
}
|
|
196
|
+
if (fill.label !== undefined && fill.labels === undefined) {
|
|
197
|
+
throw new Error(`${at}: params.fill.label requires params.fill.labels`);
|
|
198
|
+
}
|
|
183
199
|
if (step.confirm)
|
|
184
200
|
throw new Error(`${at}: fill cannot carry confirm`);
|
|
185
201
|
}
|
|
@@ -127,6 +127,13 @@ function assertValidChoices(choices, at) {
|
|
|
127
127
|
|| choice.verb === types_1.SCAN_VERBS.FILL) {
|
|
128
128
|
throw new Error(`${cat}: ${choice.verb} cannot be a choice verb`);
|
|
129
129
|
}
|
|
130
|
+
if (choice.roles !== undefined && (!Array.isArray(choice.roles) || choice.roles.length === 0
|
|
131
|
+
|| choice.roles.some((r) => typeof r !== 'string' || !r))) {
|
|
132
|
+
throw new Error(`${cat}: roles must be a non-empty array of role names`);
|
|
133
|
+
}
|
|
134
|
+
if (choice.refuse !== undefined && (typeof choice.refuse !== 'string' || !choice.refuse.trim())) {
|
|
135
|
+
throw new Error(`${cat}: refuse must be non-empty text`);
|
|
136
|
+
}
|
|
130
137
|
if (choice.confirm && !choice.confirm.prompt) {
|
|
131
138
|
throw new Error(`${cat}: confirm requires a prompt`);
|
|
132
139
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x-lt-actions on a roster field: the acts an entry offers, read the same way
|
|
3
|
+
* by the dashboard (which shows them) and the API (which runs them). Each
|
|
4
|
+
* action is exactly one act:
|
|
5
|
+
*
|
|
6
|
+
* { "label": "Missing", "resolverPayload": { "outcome": "missing" } } resolve the member row
|
|
7
|
+
* { "label": "Key in", "fill": { "payload": { "source": "key-in" }, "enterCode": true } }
|
|
8
|
+
* { "label": "Missing", "flag": { "label": "Missing" } } flag the batch key
|
|
9
|
+
* { "label": "Found it", "unflag": true } clear the flag
|
|
10
|
+
*
|
|
11
|
+
* `when` names the entry states that offer it. `roles` limits who may run it:
|
|
12
|
+
* the action shows to everyone and runs only for a person holding one of the
|
|
13
|
+
* roles; `refuse` is what anyone else is told. The server re-reads the action
|
|
14
|
+
* from the row's form schema and decides; the dashboard only displays.
|
|
15
|
+
*/
|
|
16
|
+
import { type HelpTokenContext } from './x-lt-help';
|
|
17
|
+
import { type RosterEntry, type RosterState } from './x-lt-roster';
|
|
18
|
+
export declare const X_LT_ACTIONS = "x-lt-actions";
|
|
19
|
+
export declare const ROSTER_ACTION_KINDS: {
|
|
20
|
+
readonly RESOLVE: "resolve";
|
|
21
|
+
readonly FILL: "fill";
|
|
22
|
+
readonly FLAG: "flag";
|
|
23
|
+
readonly UNFLAG: "unflag";
|
|
24
|
+
};
|
|
25
|
+
export type RosterActionKind = (typeof ROSTER_ACTION_KINDS)[keyof typeof ROSTER_ACTION_KINDS];
|
|
26
|
+
/** The separator of counted batch keys when the roster names none. */
|
|
27
|
+
export declare const ROSTER_KEY_SEPARATOR_DEFAULT = "#";
|
|
28
|
+
/** The payload key a key-in records the entered code under. */
|
|
29
|
+
export declare const ENTERED_CODE_KEY = "enteredCode";
|
|
30
|
+
export interface RosterActionDef {
|
|
31
|
+
label: string;
|
|
32
|
+
/** The entry states that offer it; the default follows the act. */
|
|
33
|
+
when?: RosterState | RosterState[];
|
|
34
|
+
/** A confirmation asked in place before firing; tokens interpolate per entry. */
|
|
35
|
+
confirm?: string;
|
|
36
|
+
/** Resolve the entry's member row with this canned payload (a query set). */
|
|
37
|
+
resolverPayload?: Record<string, unknown>;
|
|
38
|
+
/** Fill the entry's batch key; `enterCode` asks for the code and checks it against the key. */
|
|
39
|
+
fill?: {
|
|
40
|
+
payload?: Record<string, unknown>;
|
|
41
|
+
enterCode?: boolean;
|
|
42
|
+
};
|
|
43
|
+
/** Flag the entry's batch key. */
|
|
44
|
+
flag?: {
|
|
45
|
+
label: string;
|
|
46
|
+
payload?: Record<string, unknown>;
|
|
47
|
+
};
|
|
48
|
+
/** Clear the entry's flag. */
|
|
49
|
+
unflag?: true;
|
|
50
|
+
/** Runs only for a person holding one of these roles. */
|
|
51
|
+
roles?: string[];
|
|
52
|
+
/** What a person without the roles is told. */
|
|
53
|
+
refuse?: string;
|
|
54
|
+
}
|
|
55
|
+
/** The one act an action declares, or null when it declares none or several. */
|
|
56
|
+
export declare function rosterActionKind(action: RosterActionDef): RosterActionKind | null;
|
|
57
|
+
/** The field's actions with a label and exactly one act, in declared order. */
|
|
58
|
+
export declare function readRosterActions(fieldSchema: Record<string, unknown> | null | undefined): RosterActionDef[];
|
|
59
|
+
/**
|
|
60
|
+
* True when the entry offers the action: the entry is in one of its states,
|
|
61
|
+
* and the act fits the entry (a resolve needs a member row; batch acts need
|
|
62
|
+
* a batch set).
|
|
63
|
+
*/
|
|
64
|
+
export declare function offersAction(action: RosterActionDef, entry: RosterEntry, batch: boolean): boolean;
|
|
65
|
+
/** True when a person holding `roles` may run the action. */
|
|
66
|
+
export declare function holdsActionRole(action: Pick<RosterActionDef, 'roles'>, roles: string[], superadmin?: boolean): boolean;
|
|
67
|
+
/** What a person without the action's roles is told. */
|
|
68
|
+
export declare function actionRefusal(action: Pick<RosterActionDef, 'label' | 'roles' | 'refuse'>): string;
|
|
69
|
+
/** Deep-walk a payload template: string leaves interpolate against the context; other types pass through typed. */
|
|
70
|
+
export declare function interpolatePayload(value: unknown, ctx: HelpTokenContext): unknown;
|
|
71
|
+
/** The code a batch key names, without its ordinal suffix. */
|
|
72
|
+
export declare function batchKeyCode(key: string, separator?: string): string;
|
|
73
|
+
/** The batch key's code as its label prints it: a GTIN in its EAN-13 or EAN-8 form. */
|
|
74
|
+
export declare function printedKeyCode(key: string, separator?: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* True when an entered code names the batch key's code. GTINs compare in
|
|
77
|
+
* their 14-digit form, so a UPC-A typed from the label matches its GTIN-14
|
|
78
|
+
* key; anything else compares as trimmed text.
|
|
79
|
+
*/
|
|
80
|
+
export declare function enteredCodeMatches(entered: string, key: string, separator?: string): boolean;
|