@hotmeshio/long-tail 0.22.0 → 0.22.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/accumulate.d.ts +10 -1
- package/build/api/escalations/accumulate.js +121 -34
- package/build/api/escalations/metadata.d.ts +5 -0
- package/build/api/escalations/metadata.js +6 -2
- package/build/api/escalations/resolve-batch.js +18 -11
- package/build/api/roles.js +4 -0
- package/build/api/scan-codes/badge-policy.d.ts +10 -0
- package/build/api/scan-codes/badge-policy.js +72 -0
- package/build/api/scan-codes/choice.js +18 -11
- package/build/api/scan-codes/context.d.ts +45 -1
- package/build/api/scan-codes/context.js +51 -3
- package/build/api/scan-codes/execute.js +73 -35
- package/build/api/scan-codes/grant.d.ts +27 -0
- package/build/api/scan-codes/grant.js +67 -0
- package/build/api/scan-codes/hold.d.ts +10 -0
- package/build/api/scan-codes/hold.js +98 -0
- package/build/api/scan-codes/identity.d.ts +5 -2
- package/build/api/scan-codes/identity.js +26 -8
- package/build/api/scan-codes/subject.d.ts +15 -0
- package/build/api/scan-codes/subject.js +68 -0
- package/build/api/scan-codes/verb-accumulate.d.ts +24 -0
- package/build/api/scan-codes/verb-accumulate.js +147 -0
- package/build/api/scan-codes/verb-fill.d.ts +6 -0
- package/build/api/scan-codes/verb-fill.js +152 -0
- package/build/api/scan-codes/verbs-subject.d.ts +14 -0
- package/build/api/scan-codes/verbs-subject.js +270 -0
- package/build/api/scan-codes/verbs.d.ts +7 -22
- package/build/api/scan-codes/verbs.js +35 -114
- package/build/api/workflows/invocation.d.ts +8 -4
- package/build/api/workflows/invocation.js +26 -9
- package/build/index.d.ts +1 -0
- package/build/index.js +8 -2
- package/build/lib/cli/commands/workflows.js +9 -4
- package/build/lib/db/schemas/037_scan_gtin_and_subject_grants.sql +27 -0
- package/build/routes/escalations/accumulate.js +13 -6
- package/build/routes/escalations/acting.d.ts +5 -0
- package/build/routes/escalations/acting.js +8 -1
- package/build/routes/scan-codes.js +3 -0
- package/build/sdk/index.d.ts +3 -0
- package/build/services/escalation/crud.d.ts +2 -2
- package/build/services/escalation/crud.js +4 -2
- package/build/services/escalation/facet-sql.js +8 -0
- package/build/services/escalation/sql.d.ts +4 -2
- package/build/services/escalation/sql.js +10 -2
- package/build/services/export/index.d.ts +8 -3
- package/build/services/export/index.js +15 -21
- package/build/services/iam/acting-identity.d.ts +29 -4
- package/build/services/iam/acting-identity.js +60 -17
- package/build/services/iam/ephemeral.d.ts +21 -0
- package/build/services/iam/ephemeral.js +32 -1
- package/build/services/iam/sql.d.ts +10 -0
- package/build/services/iam/sql.js +32 -3
- package/build/services/pipelines/events.js +2 -1
- package/build/services/pipelines/execution-builder.js +2 -1
- package/build/services/pipelines/queries.js +2 -1
- package/build/services/role/badge-grant.d.ts +5 -0
- package/build/services/role/badge-grant.js +36 -0
- package/build/services/role/seed.js +5 -0
- package/build/services/role/types.d.ts +14 -0
- package/build/services/role/types.js +5 -0
- package/build/services/scan-code/index.d.ts +3 -2
- package/build/services/scan-code/index.js +7 -1
- package/build/services/scan-code/parse.d.ts +23 -20
- package/build/services/scan-code/parse.js +45 -90
- package/build/services/scan-code/read.js +1 -0
- package/build/services/scan-code/sql.d.ts +3 -3
- package/build/services/scan-code/sql.js +11 -8
- package/build/services/scan-code/validate-subject.d.ts +7 -0
- package/build/services/scan-code/validate-subject.js +158 -0
- package/build/services/scan-code/validate.d.ts +7 -0
- package/build/services/scan-code/validate.js +111 -16
- package/build/services/scan-code/write.d.ts +1 -0
- package/build/services/scan-code/write.js +9 -3
- package/build/services/workflow-state.d.ts +21 -0
- package/build/services/workflow-state.js +39 -0
- package/build/shared/form-validation/field-validator.js +4 -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-scan.d.ts +52 -0
- package/build/shared/form-validation/x-lt-scan.js +166 -0
- package/build/shared/scan-code/gtin.d.ts +5 -0
- package/build/shared/scan-code/gtin.js +25 -0
- package/build/shared/scan-code/index.d.ts +2 -0
- package/build/shared/scan-code/index.js +10 -0
- package/build/shared/scan-code/parse.d.ts +46 -0
- package/build/shared/scan-code/parse.js +133 -0
- package/build/shared/workflow-state.d.ts +17 -0
- package/build/shared/workflow-state.js +29 -0
- package/build/system/mcp-servers/admin/escalations.js +8 -4
- package/build/system/mcp-servers/admin/scan-codes.js +10 -4
- package/build/system/mcp-servers/admin/schemas.d.ts +792 -23
- package/build/system/mcp-servers/admin/schemas.js +61 -4
- package/build/system/mcp-servers/admin/workflows.js +20 -31
- package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
- package/build/system/seed/tool-manifests-admin.d.ts +94 -0
- package/build/system/seed/tool-manifests-admin.js +3 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +2 -0
- package/build/types/escalation.js +3 -1
- package/build/types/facets.d.ts +14 -0
- package/build/types/index.d.ts +3 -3
- package/build/types/index.js +8 -1
- package/build/types/scan-code/constants.d.ts +182 -0
- package/build/types/{scan-code.js → scan-code/constants.js} +62 -12
- package/build/types/scan-code/index.d.ts +3 -0
- package/build/types/scan-code/index.js +17 -0
- package/build/types/scan-code/response.d.ts +140 -0
- package/build/types/scan-code/response.js +2 -0
- package/build/types/scan-code/rule.d.ts +199 -0
- package/build/types/scan-code/rule.js +2 -0
- package/build/types/startup.d.ts +3 -1
- package/dashboard/dist/assets/{AdminDashboard-Covdam48.js → AdminDashboard-DBW12qQt.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Covdam48.js.map → AdminDashboard-DBW12qQt.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CE1k6J5r.js → AgentConfigPage-CmHv8U9M.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CE1k6J5r.js.map → AgentConfigPage-CmHv8U9M.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CWJZIZP1.js → AgentDetailPage-D1scIbz-.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CWJZIZP1.js.map → AgentDetailPage-D1scIbz-.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage---Dg5ufF.js → AgentsPage-BA_ai9HJ.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage---Dg5ufF.js.map → AgentsPage-BA_ai9HJ.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-C2_5aEFW.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-C2_5aEFW.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-D3drO3-T.js → BotPicker-BZo4Kp4a.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-D3drO3-T.js.map → BotPicker-BZo4Kp4a.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-BOAWsViq.js → BulkAssignModal-BFhyxY2T.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-BOAWsViq.js.map → BulkAssignModal-BFhyxY2T.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-CvOX6vAc.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-RGgD3YZO.js.map → CapabilitiesPage-CvOX6vAc.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DNkZn87n.js → CollapsibleSection-GCJsV9Oq.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DNkZn87n.js.map → CollapsibleSection-GCJsV9Oq.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-BqzOwhPr.js → ConfirmDeleteModal-CAgYLcef.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-BqzOwhPr.js.map → ConfirmDeleteModal-CAgYLcef.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-Dik2z0M_.js +2 -0
- package/dashboard/dist/assets/{CountdownTimer-BaexQMK6.js.map → CountdownTimer-Dik2z0M_.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-D7abp0aS.js → CredentialsPage-twd2xCOW.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-D7abp0aS.js.map → CredentialsPage-twd2xCOW.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DZiWmTwJ.js → CronLabel-DdnIuudX.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DZiWmTwJ.js.map → CronLabel-DdnIuudX.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-f1o-GLM8.js → DropZone-B1Tdfddc.js} +2 -2
- package/dashboard/dist/assets/{DropZone-f1o-GLM8.js.map → DropZone-B1Tdfddc.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BdGO_w4v.js → ElapsedCell-DCctVv5R.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BdGO_w4v.js.map → ElapsedCell-DCctVv5R.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-DIDcF5Yu.js → EntityTimelinePanel-CMnskyWv.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-DIDcF5Yu.js.map → EntityTimelinePanel-CMnskyWv.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-C28rn9XC.js → EscalationListSchemaPage-VfCn6WDb.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-C28rn9XC.js.map → EscalationListSchemaPage-VfCn6WDb.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListView-CkBnkpDJ.js → EscalationListView-CGQZxcC-.js} +2 -2
- package/dashboard/dist/assets/{EscalationListView-CkBnkpDJ.js.map → EscalationListView-CGQZxcC-.js.map} +1 -1
- package/dashboard/dist/assets/EscalationSchemaPage-BX0tx-PM.js +9 -0
- package/dashboard/dist/assets/EscalationSchemaPage-BX0tx-PM.js.map +1 -0
- package/dashboard/dist/assets/EscalationTimeline-DKoSM56J.js +2 -0
- package/dashboard/dist/assets/EscalationTimeline-DKoSM56J.js.map +1 -0
- package/dashboard/dist/assets/{EscalationTitleSelect-CzKfavri.js → EscalationTitleSelect-DWGLBOmS.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-CzKfavri.js.map → EscalationTitleSelect-DWGLBOmS.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-Tdu3Yx2c.js → EscalationsOverview-C2XoguaA.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-Tdu3Yx2c.js.map → EscalationsOverview-C2XoguaA.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DiIxOJwO.js → EventTable-CBUWq7--.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DiIxOJwO.js.map → EventTable-CBUWq7--.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-CvMBCVIo.js → FilterBar-8IdbleZ9.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-CvMBCVIo.js.map → FilterBar-8IdbleZ9.js.map} +1 -1
- package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js +2 -0
- package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-DO-yyhi6.js → GraphInvokePage-CUvoPzsW.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DO-yyhi6.js.map → GraphInvokePage-CUvoPzsW.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-DSS3eHR2.js → HomePage-BP7v9GLJ.js} +2 -2
- package/dashboard/dist/assets/{HomePage-DSS3eHR2.js.map → HomePage-BP7v9GLJ.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-C3-Tqqub.js → ListToolbar-Cnacuwoy.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-C3-Tqqub.js.map → ListToolbar-Cnacuwoy.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DEJmsdVi.js → McpOverview-C2JoNoDA.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DEJmsdVi.js.map → McpOverview-C2JoNoDA.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-C_nih0w-.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-C_nih0w-.js.map +1 -0
- package/dashboard/dist/assets/{McpQueryPage-BBcG_UuU.js → McpQueryPage-U_wNXow2.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-BBcG_UuU.js.map → McpQueryPage-U_wNXow2.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-C6xw0kBg.js → McpRunDetailPage-DtKoJq6J.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-C6xw0kBg.js.map → McpRunDetailPage-DtKoJq6J.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-CRQqrF4Q.js → McpRunsPage-CnYtfGhf.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CRQqrF4Q.js.map → McpRunsPage-CnYtfGhf.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-DADRJOUl.js → NamespacePill-DwM5pNA4.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-DADRJOUl.js.map → NamespacePill-DwM5pNA4.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-Dlfwzf-0.js → OperationsPage-C7hupIer.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-Dlfwzf-0.js.map → OperationsPage-C7hupIer.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-DoiDGZ9R.js → OperatorDashboard-fVuLn2D5.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DoiDGZ9R.js.map → OperatorDashboard-fVuLn2D5.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Csq434-v.js → PageHeader-CMd3f4bz.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Csq434-v.js.map → PageHeader-CMd3f4bz.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-CSnk1p5A.js → PageHeaderWithStats-DHj8Mqox.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-CSnk1p5A.js.map → PageHeaderWithStats-DHj8Mqox.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-BzbA4Prr.js → PersonaDetailPage-C-4o8lPw.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-BzbA4Prr.js.map → PersonaDetailPage-C-4o8lPw.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-B36yn4hU.js → PersonasPage-BL1FwLmv.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-B36yn4hU.js.map → PersonasPage-BL1FwLmv.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-BkD4YfDf.js → PortalPage-tJG5sgb1.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-BkD4YfDf.js.map → PortalPage-tJG5sgb1.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BT0eiBWY.js → ProcessDetailPage-Dz_jY4Yt.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BT0eiBWY.js.map → ProcessDetailPage-Dz_jY4Yt.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-BEqeeNae.js → ProcessesListPage-Cbn9cter.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-BEqeeNae.js.map → ProcessesListPage-Cbn9cter.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js +8 -0
- package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js.map +1 -0
- package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-BafrASDX.js → RolePill-Di2CAHuD.js} +2 -2
- package/dashboard/dist/assets/{RolePill-BafrASDX.js.map → RolePill-Di2CAHuD.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-80quJU5-.js → RolesPage-NwmMvZFa.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-80quJU5-.js.map → RolesPage-NwmMvZFa.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BoePhWVD.js → RunAsSelector-tgEooTyU.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BoePhWVD.js.map → RunAsSelector-tgEooTyU.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js +2 -0
- package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js.map +1 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-B275l6r_.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-B275l6r_.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-b6MIBiYD.js → ScopeBadge-CSItPVOH.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-b6MIBiYD.js.map → ScopeBadge-CSItPVOH.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-9ITrei_d.js → StickyPagination-CsTI_gvJ.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-9ITrei_d.js.map → StickyPagination-CsTI_gvJ.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-BkYvEHFY.js → StreamMessageDetail-auRlvjTh.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-BkYvEHFY.js.map → StreamMessageDetail-auRlvjTh.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-B1rotFix.js → SwimlaneTimeline-BLoVHYAd.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-B1rotFix.js.map → SwimlaneTimeline-BLoVHYAd.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-ZrIIrEUP.js → TagInput-CAgdLN_b.js} +2 -2
- package/dashboard/dist/assets/{TagInput-ZrIIrEUP.js.map → TagInput-CAgdLN_b.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-zhn_U_eC.js → TaskDetailPage-BPsZ1bK_.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-zhn_U_eC.js.map → TaskDetailPage-BPsZ1bK_.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-DkQ1uc6y.js → TaskQueuePill-h0oorVMe.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-DkQ1uc6y.js.map → TaskQueuePill-h0oorVMe.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CNbNeagx.js → TasksListPage-BNGM74yT.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CNbNeagx.js.map → TasksListPage-BNGM74yT.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-0YVMBwls.js → TimeAgo-BnAHXGK7.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-0YVMBwls.js.map → TimeAgo-BnAHXGK7.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DB7r3np8.js → TimestampCell-J4yae6mc.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DB7r3np8.js.map → TimestampCell-J4yae6mc.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-Baxm02L6.js → ToolPill-CQCsVdzD.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-Baxm02L6.js.map → ToolPill-CQCsVdzD.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BLfA02wv.js → ToolTestPanel-BdzzgXDu.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BLfA02wv.js.map → ToolTestPanel-BdzzgXDu.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-eAqPKShq.js → TopicDetailPage-DJKg8lb7.js} +4 -4
- package/dashboard/dist/assets/{TopicDetailPage-eAqPKShq.js.map → TopicDetailPage-DJKg8lb7.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-BNNWD-zl.js → TopicsPage-DQV0WxG6.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-BNNWD-zl.js.map → TopicsPage-DQV0WxG6.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-Pw46tO_k.js → UserName-Ct09nGh5.js} +2 -2
- package/dashboard/dist/assets/{UserName-Pw46tO_k.js.map → UserName-Ct09nGh5.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DvA51lT3.js → WorkflowExecutionPage-B5WJOsee.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DvA51lT3.js.map → WorkflowExecutionPage-B5WJOsee.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-ZepbO_ny.js → WorkflowPill-Dg7BDTyM.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-ZepbO_ny.js.map → WorkflowPill-Dg7BDTyM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DFDTwnhn.js → WorkflowsDashboard-Hc87TRgD.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DFDTwnhn.js.map → WorkflowsDashboard-Hc87TRgD.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-5i2Tcy-p.js → WorkflowsOverview-CJQbyOj-.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-5i2Tcy-p.js.map → WorkflowsOverview-CJQbyOj-.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-p4VEYZS0.js → YamlWorkflowDetailPage-BMeED677.js} +8 -8
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-p4VEYZS0.js.map → YamlWorkflowDetailPage-BMeED677.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-Cq-hMVxl.js → YamlWorkflowsPage-BMMg0Id6.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-Cq-hMVxl.js.map → YamlWorkflowsPage-BMMg0Id6.js.map} +1 -1
- package/dashboard/dist/assets/{agents-EyBPJMYa.js → agents-CdFkgFvg.js} +2 -2
- package/dashboard/dist/assets/{agents-EyBPJMYa.js.map → agents-CdFkgFvg.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DX6jjqtF.js → bots-Mj3LHWWg.js} +2 -2
- package/dashboard/dist/assets/{bots-DX6jjqtF.js.map → bots-Mj3LHWWg.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-ZdLv9xBQ.js → capabilities-Dw1ObK2-.js} +2 -2
- package/dashboard/dist/assets/{capabilities-ZdLv9xBQ.js.map → capabilities-Dw1ObK2-.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CpvZaJuw.js → controlplane-DcNE1APv.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CpvZaJuw.js.map → controlplane-DcNE1APv.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Mvsze5eV.js → escalation-columns-D364Trpy.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Mvsze5eV.js.map → escalation-columns-D364Trpy.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cn8uJsd7.js → index-B3veJ698.js} +2 -2
- package/dashboard/dist/assets/{index-Cn8uJsd7.js.map → index-B3veJ698.js.map} +1 -1
- package/dashboard/dist/assets/index-BQeHJHYN.js +67 -0
- package/dashboard/dist/assets/index-BQeHJHYN.js.map +1 -0
- package/dashboard/dist/assets/{index-D-Xs4rAW.js → index-BRGTmoYY.js} +2 -2
- package/dashboard/dist/assets/{index-D-Xs4rAW.js.map → index-BRGTmoYY.js.map} +1 -1
- package/dashboard/dist/assets/{index-DkrBFFSO.js → index-Bd6-KmBE.js} +3 -3
- package/dashboard/dist/assets/{index-DkrBFFSO.js.map → index-Bd6-KmBE.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bhb89oHH.js → index-BiVce3n0.js} +2 -2
- package/dashboard/dist/assets/{index-Bhb89oHH.js.map → index-BiVce3n0.js.map} +1 -1
- package/dashboard/dist/assets/{index-z5Hpeidu.js → index-BmNAVd4s.js} +2 -2
- package/dashboard/dist/assets/{index-z5Hpeidu.js.map → index-BmNAVd4s.js.map} +1 -1
- package/dashboard/dist/assets/{index-BbCjGO3M.js → index-Bq5XNEzD.js} +2 -2
- package/dashboard/dist/assets/{index-BbCjGO3M.js.map → index-Bq5XNEzD.js.map} +1 -1
- package/dashboard/dist/assets/{index-DGmzBY9D.js → index-DPStdq4T.js} +2 -2
- package/dashboard/dist/assets/{index-DGmzBY9D.js.map → index-DPStdq4T.js.map} +1 -1
- package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
- package/dashboard/dist/assets/{index-PfSRKerc.js → index-DkcI4V_H.js} +2 -2
- package/dashboard/dist/assets/{index-PfSRKerc.js.map → index-DkcI4V_H.js.map} +1 -1
- package/dashboard/dist/assets/{index-oFKUFGQL.js → index-Dyotfa_k.js} +2 -2
- package/dashboard/dist/assets/{index-oFKUFGQL.js.map → index-Dyotfa_k.js.map} +1 -1
- package/dashboard/dist/assets/{index-Eo-l3Lqo.js → index-MDD4JYtu.js} +2 -2
- package/dashboard/dist/assets/{index-Eo-l3Lqo.js.map → index-MDD4JYtu.js.map} +1 -1
- package/dashboard/dist/assets/index-WSm8bgE7.js +3 -0
- package/dashboard/dist/assets/index-WSm8bgE7.js.map +1 -0
- package/dashboard/dist/assets/{index-DZhtP2Ok.js → index-eDm6cz0F.js} +2 -2
- package/dashboard/dist/assets/{index-DZhtP2Ok.js.map → index-eDm6cz0F.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-CgloEkaf.js → knowledge-Bafewjxk.js} +2 -2
- package/dashboard/dist/assets/{knowledge-CgloEkaf.js.map → knowledge-Bafewjxk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-o-sGX2ST.js → mcp-query-BzTtIG90.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-o-sGX2ST.js.map → mcp-query-BzTtIG90.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Bix7QYO7.js → mcp-vLIutbnc.js} +2 -2
- package/dashboard/dist/assets/{mcp-Bix7QYO7.js.map → mcp-vLIutbnc.js.map} +1 -1
- package/dashboard/dist/assets/{personas-30azkJ_s.js → personas-WD40EDS_.js} +2 -2
- package/dashboard/dist/assets/{personas-30azkJ_s.js.map → personas-WD40EDS_.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Bfk2GFK7.js → pipelines-DFwULWs3.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Bfk2GFK7.js.map → pipelines-DFwULWs3.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CpdopewW.js → tasks-La_-WAUn.js} +2 -2
- package/dashboard/dist/assets/{tasks-CpdopewW.js.map → tasks-La_-WAUn.js.map} +1 -1
- package/dashboard/dist/assets/{topics--bvCV9Yp.js → topics-CzYMlvqm.js} +2 -2
- package/dashboard/dist/assets/{topics--bvCV9Yp.js.map → topics-CzYMlvqm.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-Da0lPmj3.js → useDebouncedValue-C0FQyANW.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Da0lPmj3.js.map → useDebouncedValue-C0FQyANW.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DD_Esl6n.js → useNamespace-WW_XjAb3.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DD_Esl6n.js.map → useNamespace-WW_XjAb3.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-AeAhZJJk.js → useYamlActivityEvents-B3YxPeFt.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-AeAhZJJk.js.map → useYamlActivityEvents-B3YxPeFt.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-B7OcUM6b.js → vendor-icons-CeVtUKyP.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-B7OcUM6b.js.map → vendor-icons-CeVtUKyP.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BHAOOGvn.js → yaml-workflows-COHOjdhF.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BHAOOGvn.js.map → yaml-workflows-COHOjdhF.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/accumulator.md +37 -1
- package/docs/api/mcp/admin.md +3 -2
- package/docs/api/sdk/escalations.md +6 -0
- package/docs/api/sdk/exports.md +1 -1
- package/docs/api/sdk/workflows.md +23 -4
- package/docs/cli.md +1 -1
- package/docs/dashboard.md +2 -2
- package/docs/faceted-routing.md +2 -0
- package/docs/hitl/x-lt-scan.md +51 -0
- package/docs/hitl/x-lt-widget.md +5 -0
- package/docs/hitl-guide.md +2 -0
- package/docs/scan-codes.md +252 -19
- package/package.json +1 -1
- package/build/types/scan-code.d.ts +0 -308
- package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js.map +0 -1
- package/dashboard/dist/assets/CapabilitiesPage-RGgD3YZO.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-BaexQMK6.js +0 -2
- package/dashboard/dist/assets/EscalationSchemaPage-W5r0A1kj.js +0 -9
- package/dashboard/dist/assets/EscalationSchemaPage-W5r0A1kj.js.map +0 -1
- package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js +0 -2
- package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-DYJr16l7.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-DYJr16l7.js.map +0 -1
- package/dashboard/dist/assets/ResolverForm-BwgjIX97.js +0 -7
- package/dashboard/dist/assets/ResolverForm-BwgjIX97.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js.map +0 -1
- package/dashboard/dist/assets/ScanCodesPage-Cu1bKEix.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-Cu1bKEix.js.map +0 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js.map +0 -1
- package/dashboard/dist/assets/index-B_GT23TE.js +0 -3
- package/dashboard/dist/assets/index-B_GT23TE.js.map +0 -1
- package/dashboard/dist/assets/index-CgUcYveM.js +0 -67
- package/dashboard/dist/assets/index-CgUcYveM.js.map +0 -1
- package/dashboard/dist/assets/index-Dh8MJl3L.css +0 -1
package/build/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * as TaskService from './services/task';
|
|
|
12
12
|
export * as EscalationService from './services/escalation';
|
|
13
13
|
export * as ConfigService from './services/config';
|
|
14
14
|
export * as UserService from './services/user';
|
|
15
|
+
export { assertValidScheme as assertValidScanScheme, assertValidSteps as assertValidScanSteps, assertValidIdentityRule as assertValidScanIdentityRule, isValidGtin, normalizeGtin, type ScanSchemeInput, type ScanRuleInput, } from './services/scan-code';
|
|
15
16
|
export * as TopicService from './services/topics';
|
|
16
17
|
export { seedSystemTopics, seedConfigTopics } from './services/topics/system-topics';
|
|
17
18
|
export { ltConfig } from './modules/ltconfig';
|
package/build/index.js
CHANGED
|
@@ -36,8 +36,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = void 0;
|
|
39
|
+
exports.McpServer = exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.normalizeGtin = exports.isValidGtin = exports.assertValidScanIdentityRule = exports.assertValidScanSteps = exports.assertValidScanScheme = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
|
|
40
|
+
exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = void 0;
|
|
41
41
|
const config_1 = require("./modules/config");
|
|
42
42
|
const logger_1 = require("./lib/logger");
|
|
43
43
|
const midnight_1 = require("./themes/midnight");
|
|
@@ -70,6 +70,12 @@ exports.TaskService = __importStar(require("./services/task"));
|
|
|
70
70
|
exports.EscalationService = __importStar(require("./services/escalation"));
|
|
71
71
|
exports.ConfigService = __importStar(require("./services/config"));
|
|
72
72
|
exports.UserService = __importStar(require("./services/user"));
|
|
73
|
+
var scan_code_1 = require("./services/scan-code");
|
|
74
|
+
Object.defineProperty(exports, "assertValidScanScheme", { enumerable: true, get: function () { return scan_code_1.assertValidScheme; } });
|
|
75
|
+
Object.defineProperty(exports, "assertValidScanSteps", { enumerable: true, get: function () { return scan_code_1.assertValidSteps; } });
|
|
76
|
+
Object.defineProperty(exports, "assertValidScanIdentityRule", { enumerable: true, get: function () { return scan_code_1.assertValidIdentityRule; } });
|
|
77
|
+
Object.defineProperty(exports, "isValidGtin", { enumerable: true, get: function () { return scan_code_1.isValidGtin; } });
|
|
78
|
+
Object.defineProperty(exports, "normalizeGtin", { enumerable: true, get: function () { return scan_code_1.normalizeGtin; } });
|
|
73
79
|
exports.TopicService = __importStar(require("./services/topics"));
|
|
74
80
|
var system_topics_1 = require("./services/topics/system-topics");
|
|
75
81
|
Object.defineProperty(exports, "seedSystemTopics", { enumerable: true, get: function () { return system_topics_1.seedSystemTopics; } });
|
|
@@ -45,6 +45,7 @@ exports.terminateWorkflow = terminateWorkflow;
|
|
|
45
45
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
46
46
|
const client_1 = require("../client");
|
|
47
47
|
const format_1 = require("../format");
|
|
48
|
+
const workflow_state_1 = require("../../../shared/workflow-state");
|
|
48
49
|
const COLUMNS = [
|
|
49
50
|
{ key: 'workflow_type', label: 'Type', width: 24 },
|
|
50
51
|
{ key: 'task_queue', label: 'Queue', width: 16 },
|
|
@@ -72,13 +73,17 @@ async function invokeWorkflow(type, opts) {
|
|
|
72
73
|
console.log(`\n ${picocolors_1.default.green('✓')} Started ${picocolors_1.default.bold(type)} → ${picocolors_1.default.dim(data.workflowId)}\n`);
|
|
73
74
|
}
|
|
74
75
|
async function getWorkflowStatus(id, opts) {
|
|
75
|
-
const data = await (0, client_1.apiFetch)(`/workflows
|
|
76
|
+
const data = await (0, client_1.apiFetch)(`/workflows/${encodeURIComponent(id)}/status`);
|
|
76
77
|
if (opts.json) {
|
|
77
78
|
console.log(JSON.stringify(data, null, 2));
|
|
78
79
|
return;
|
|
79
80
|
}
|
|
80
|
-
const
|
|
81
|
-
|
|
81
|
+
const state = data.state === workflow_state_1.WORKFLOW_STATES.COMPLETED
|
|
82
|
+
? picocolors_1.default.green('completed')
|
|
83
|
+
: data.state === workflow_state_1.WORKFLOW_STATES.FAILED
|
|
84
|
+
? picocolors_1.default.red(data.terminated ? 'failed (terminated)' : 'failed')
|
|
85
|
+
: picocolors_1.default.blue('running');
|
|
86
|
+
console.log(`\n ${data.workflowId} ${state}${data.error ? picocolors_1.default.dim(` ${data.error}`) : ''}\n`);
|
|
82
87
|
}
|
|
83
88
|
async function getWorkflowResult(id, opts) {
|
|
84
89
|
const { server, token } = await (await Promise.resolve().then(() => __importStar(require('../auth')))).resolveAuth();
|
|
@@ -121,6 +126,6 @@ async function getWorkflowEnvelopes(id, opts) {
|
|
|
121
126
|
console.log();
|
|
122
127
|
}
|
|
123
128
|
async function terminateWorkflow(id) {
|
|
124
|
-
await (0, client_1.apiFetch)(`/workflows
|
|
129
|
+
await (0, client_1.apiFetch)(`/workflows/${encodeURIComponent(id)}/terminate`, { method: 'POST' });
|
|
125
130
|
console.log(`\n ${picocolors_1.default.green('✓')} Terminated ${picocolors_1.default.dim(id)}\n`);
|
|
126
131
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- Migration 037: GTIN scan schemes and subject-bound acting grants
|
|
2
|
+
--
|
|
3
|
+
-- encoding 'gtin': a scheme whose codes are manufacturer barcodes (UPC-A,
|
|
4
|
+
-- EAN-13, EAN-8, GTIN-14). The code carries no scheme or category; the
|
|
5
|
+
-- check digit identifies it, and the scheme's single rule is category '0'.
|
|
6
|
+
--
|
|
7
|
+
-- grant_scope (identity kind only):
|
|
8
|
+
-- 'action' each mutating act spends one use of the grant.
|
|
9
|
+
-- 'subject' the first act binds the grant to the held subject (the item
|
|
10
|
+
-- the station is holding); further acts on that same subject do
|
|
11
|
+
-- not count, and the grant cannot act on any other subject.
|
|
12
|
+
--
|
|
13
|
+
-- lt_ephemeral_credentials.bind_on_use / bound_ref carry that binding.
|
|
14
|
+
|
|
15
|
+
ALTER TABLE lt_config_scan_schemes
|
|
16
|
+
DROP CONSTRAINT IF EXISTS lt_config_scan_schemes_encoding_check;
|
|
17
|
+
ALTER TABLE lt_config_scan_schemes
|
|
18
|
+
ADD CONSTRAINT lt_config_scan_schemes_encoding_check
|
|
19
|
+
CHECK (encoding IN ('fixed', 'delimited', 'gtin'));
|
|
20
|
+
|
|
21
|
+
ALTER TABLE lt_config_scan_schemes
|
|
22
|
+
ADD COLUMN IF NOT EXISTS grant_scope TEXT NOT NULL DEFAULT 'action'
|
|
23
|
+
CHECK (grant_scope IN ('action', 'subject'));
|
|
24
|
+
|
|
25
|
+
ALTER TABLE lt_ephemeral_credentials
|
|
26
|
+
ADD COLUMN IF NOT EXISTS bind_on_use BOOLEAN NOT NULL DEFAULT FALSE,
|
|
27
|
+
ADD COLUMN IF NOT EXISTS bound_ref TEXT;
|
|
@@ -45,7 +45,7 @@ function registerAccumulateRoutes(router) {
|
|
|
45
45
|
/**
|
|
46
46
|
* POST /api/escalations/accumulate-by-signal-key
|
|
47
47
|
* Add one item to an accumulator escalation by its signal_key.
|
|
48
|
-
* Body: { signalKey, itemKey, payload?, metadata?, reciprocal? }
|
|
48
|
+
* Body: { signalKey, itemKey, payload?, metadata?, reciprocal?, initiatedBy? }
|
|
49
49
|
*/
|
|
50
50
|
router.post('/accumulate-by-signal-key', async (req, res) => {
|
|
51
51
|
const result = await api.accumulateItemBySignalKey({
|
|
@@ -54,6 +54,7 @@ function registerAccumulateRoutes(router) {
|
|
|
54
54
|
payload: req.body?.payload,
|
|
55
55
|
metadata: req.body?.metadata,
|
|
56
56
|
reciprocal: req.body?.reciprocal,
|
|
57
|
+
initiatedBy: req.body?.initiatedBy,
|
|
57
58
|
}, req.auth);
|
|
58
59
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
59
60
|
});
|
|
@@ -61,7 +62,7 @@ function registerAccumulateRoutes(router) {
|
|
|
61
62
|
* POST /api/escalations/accumulate-by-metadata
|
|
62
63
|
* Add one item to the highest priority pending accumulator whose metadata
|
|
63
64
|
* contains the key/value.
|
|
64
|
-
* Body: { key, value, itemKey, payload?, metadata?, restrictRoles?, reciprocal? }
|
|
65
|
+
* Body: { key, value, itemKey, payload?, metadata?, restrictRoles?, container?, reciprocal?, initiatedBy? }
|
|
65
66
|
*/
|
|
66
67
|
router.post('/accumulate-by-metadata', async (req, res) => {
|
|
67
68
|
const result = await api.accumulateItemByMetadata({
|
|
@@ -71,25 +72,28 @@ function registerAccumulateRoutes(router) {
|
|
|
71
72
|
payload: req.body?.payload,
|
|
72
73
|
metadata: req.body?.metadata,
|
|
73
74
|
restrictRoles: req.body?.restrictRoles,
|
|
75
|
+
container: req.body?.container,
|
|
74
76
|
reciprocal: req.body?.reciprocal,
|
|
77
|
+
initiatedBy: req.body?.initiatedBy,
|
|
75
78
|
}, req.auth);
|
|
76
79
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
77
80
|
});
|
|
78
81
|
/**
|
|
79
82
|
* POST /api/escalations/remove-item-by-signal-key
|
|
80
|
-
* Body: { signalKey, itemKey, reciprocal? }
|
|
83
|
+
* Body: { signalKey, itemKey, reciprocal?, initiatedBy? }
|
|
81
84
|
*/
|
|
82
85
|
router.post('/remove-item-by-signal-key', async (req, res) => {
|
|
83
86
|
const result = await api.removeItemBySignalKey({
|
|
84
87
|
signalKey: req.body?.signalKey,
|
|
85
88
|
itemKey: req.body?.itemKey,
|
|
86
89
|
reciprocal: req.body?.reciprocal,
|
|
90
|
+
initiatedBy: req.body?.initiatedBy,
|
|
87
91
|
}, req.auth);
|
|
88
92
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
89
93
|
});
|
|
90
94
|
/**
|
|
91
95
|
* POST /api/escalations/remove-item-by-metadata
|
|
92
|
-
* Body: { key, value, itemKey, restrictRoles?, reciprocal? }
|
|
96
|
+
* Body: { key, value, itemKey, restrictRoles?, reciprocal?, initiatedBy? }
|
|
93
97
|
*/
|
|
94
98
|
router.post('/remove-item-by-metadata', async (req, res) => {
|
|
95
99
|
const result = await api.removeItemByMetadata({
|
|
@@ -98,6 +102,7 @@ function registerAccumulateRoutes(router) {
|
|
|
98
102
|
itemKey: req.body?.itemKey,
|
|
99
103
|
restrictRoles: req.body?.restrictRoles,
|
|
100
104
|
reciprocal: req.body?.reciprocal,
|
|
105
|
+
initiatedBy: req.body?.initiatedBy,
|
|
101
106
|
}, req.auth);
|
|
102
107
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
103
108
|
});
|
|
@@ -115,7 +120,7 @@ function registerAccumulateRoutes(router) {
|
|
|
115
120
|
* the add that reaches max answers { outcome: 'completed', signaled } and the
|
|
116
121
|
* waiting workflow resumes with the collection. Claim-agnostic unless
|
|
117
122
|
* assertClaim: true.
|
|
118
|
-
* Body: { itemKey, payload?, metadata?, assertClaim?, reciprocal? }
|
|
123
|
+
* Body: { itemKey, payload?, metadata?, assertClaim?, reciprocal?, initiatedBy? }
|
|
119
124
|
*/
|
|
120
125
|
router.post('/:id/accumulate', async (req, res) => {
|
|
121
126
|
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
@@ -128,13 +133,14 @@ function registerAccumulateRoutes(router) {
|
|
|
128
133
|
metadata: req.body?.metadata,
|
|
129
134
|
assertClaim: req.body?.assertClaim,
|
|
130
135
|
reciprocal: req.body?.reciprocal,
|
|
136
|
+
initiatedBy: req.body?.initiatedBy,
|
|
131
137
|
}, auth);
|
|
132
138
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
133
139
|
});
|
|
134
140
|
/**
|
|
135
141
|
* POST /api/escalations/:id/remove-item
|
|
136
142
|
* Remove one held item; the row stays pending and the waiter never wakes.
|
|
137
|
-
* Body: { itemKey, reciprocal? }
|
|
143
|
+
* Body: { itemKey, reciprocal?, initiatedBy? }
|
|
138
144
|
*/
|
|
139
145
|
router.post('/:id/remove-item', async (req, res) => {
|
|
140
146
|
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
@@ -144,6 +150,7 @@ function registerAccumulateRoutes(router) {
|
|
|
144
150
|
id: req.params.id,
|
|
145
151
|
itemKey: req.body?.itemKey,
|
|
146
152
|
reciprocal: req.body?.reciprocal,
|
|
153
|
+
initiatedBy: req.body?.initiatedBy,
|
|
147
154
|
}, auth);
|
|
148
155
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
149
156
|
});
|
|
@@ -2,6 +2,11 @@ import type { Request, Response } from 'express';
|
|
|
2
2
|
import type { LTApiAuth } from '../../types/sdk';
|
|
3
3
|
/** The header a shared station device rides its badge grant on. */
|
|
4
4
|
export declare const ACTING_TOKEN_HEADER = "x-lt-acting-token";
|
|
5
|
+
/**
|
|
6
|
+
* Uses the grant has left after this request spent one: a count, or
|
|
7
|
+
* `unbounded` while only the TTL limits it. The client retires its grant on 0.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ACTING_REMAINING_HEADER = "x-lt-acting-remaining";
|
|
5
10
|
/**
|
|
6
11
|
* The effective actor for an escalation WORK verb (claim, release, resolve):
|
|
7
12
|
* the badged person when an acting grant rides the request, otherwise the
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ACTING_TOKEN_HEADER = void 0;
|
|
3
|
+
exports.ACTING_REMAINING_HEADER = exports.ACTING_TOKEN_HEADER = void 0;
|
|
4
4
|
exports.effectiveWorkAuth = effectiveWorkAuth;
|
|
5
5
|
const acting_identity_1 = require("../../services/iam/acting-identity");
|
|
6
6
|
/** The header a shared station device rides its badge grant on. */
|
|
7
7
|
exports.ACTING_TOKEN_HEADER = 'x-lt-acting-token';
|
|
8
|
+
/**
|
|
9
|
+
* Uses the grant has left after this request spent one: a count, or
|
|
10
|
+
* `unbounded` while only the TTL limits it. The client retires its grant on 0.
|
|
11
|
+
*/
|
|
12
|
+
exports.ACTING_REMAINING_HEADER = 'x-lt-acting-remaining';
|
|
8
13
|
/**
|
|
9
14
|
* The effective actor for an escalation WORK verb (claim, release, resolve):
|
|
10
15
|
* the badged person when an acting grant rides the request, otherwise the
|
|
@@ -21,5 +26,7 @@ async function effectiveWorkAuth(req, res) {
|
|
|
21
26
|
res.status(401).json({ error: resolved.error });
|
|
22
27
|
return null;
|
|
23
28
|
}
|
|
29
|
+
const { remaining } = resolved.grant;
|
|
30
|
+
res.setHeader(exports.ACTING_REMAINING_HEADER, remaining === null ? 'unbounded' : String(remaining));
|
|
24
31
|
return resolved.auth;
|
|
25
32
|
}
|
|
@@ -49,6 +49,8 @@ router.post('/execute', async (req, res) => {
|
|
|
49
49
|
code: req.body.code,
|
|
50
50
|
actingToken: req.body.actingToken,
|
|
51
51
|
previousActingToken: req.body.previousActingToken,
|
|
52
|
+
subject: req.body.subject,
|
|
53
|
+
stationRole: req.body.stationRole,
|
|
52
54
|
}, req.auth);
|
|
53
55
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
54
56
|
});
|
|
@@ -102,6 +104,7 @@ router.put('/schemes/:version', auth_1.requireRoleManager, async (req, res) => {
|
|
|
102
104
|
kind: req.body.kind,
|
|
103
105
|
grant_ttl_seconds: req.body.grant_ttl_seconds,
|
|
104
106
|
grant_max_uses: req.body.grant_max_uses,
|
|
107
|
+
grant_scope: req.body.grant_scope,
|
|
105
108
|
enabled: req.body.enabled,
|
|
106
109
|
});
|
|
107
110
|
res.status(result.status).json(result.data ?? { error: result.error });
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -222,6 +222,8 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
222
222
|
metadata?: Record<string, any>;
|
|
223
223
|
restrictRoles?: string[];
|
|
224
224
|
extraFacets?: Record<string, any>;
|
|
225
|
+
availability?: import("..").ScanAvailability;
|
|
226
|
+
assertId?: string;
|
|
225
227
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
226
228
|
resolveBatchItem: (input: {
|
|
227
229
|
id: string;
|
|
@@ -254,6 +256,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
254
256
|
key: string;
|
|
255
257
|
value: string;
|
|
256
258
|
restrictRoles?: string[];
|
|
259
|
+
container?: import("..").ContainerSelector;
|
|
257
260
|
} & Omit<import("../api/escalations/accumulate").AccumulateItemInput, "assertClaim">, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
258
261
|
removeItem: (input: {
|
|
259
262
|
id: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { publishEscalationEvent } from '../../lib/events/publish';
|
|
2
|
-
import type { LTEscalationRecord } from '../../types';
|
|
2
|
+
import type { LTEscalationRecord, ScanAvailability } from '../../types';
|
|
3
3
|
import type { CreateEscalationInput, ClaimResult } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Every escalation write publishes an event AND drops this container's cached
|
|
@@ -256,4 +256,4 @@ export interface ResolveByMetadataResult {
|
|
|
256
256
|
* business logic over the shared table, so it runs as one atomic statement on
|
|
257
257
|
* `hmsh_escalations` rather than through the generic SDK resolve.
|
|
258
258
|
*/
|
|
259
|
-
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>;
|
|
259
|
+
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, availability?: ScanAvailability | null): Promise<ResolveByMetadataResult>;
|
|
@@ -28,6 +28,7 @@ exports.resolveByMetadataAtomic = resolveByMetadataAtomic;
|
|
|
28
28
|
const db_1 = require("../../lib/db");
|
|
29
29
|
const publish_1 = require("../../lib/events/publish");
|
|
30
30
|
const escalation_wire_1 = require("../../lib/events/escalation-wire");
|
|
31
|
+
const scan_code_1 = require("../../types/scan-code");
|
|
31
32
|
const escalation_1 = require("../../types/escalation");
|
|
32
33
|
const uuid_1 = require("../../lib/uuid");
|
|
33
34
|
const client_1 = require("./client");
|
|
@@ -600,7 +601,7 @@ async function claimByMetadata(key, value, userId, durationMinutes = 30, metadat
|
|
|
600
601
|
* business logic over the shared table, so it runs as one atomic statement on
|
|
601
602
|
* `hmsh_escalations` rather than through the generic SDK resolve.
|
|
602
603
|
*/
|
|
603
|
-
async function resolveByMetadataAtomic(key, value, userId, resolverPayload, metadata, writeAllRoles, writeSelfRoles, enforcingRoles, assertId, extraFacets) {
|
|
604
|
+
async function resolveByMetadataAtomic(key, value, userId, resolverPayload, metadata, writeAllRoles, writeSelfRoles, enforcingRoles, assertId, extraFacets, availability) {
|
|
604
605
|
await (0, client_1.ensureEscalationCompatView)();
|
|
605
606
|
const pool = (0, db_1.getPool)();
|
|
606
607
|
// The statement's filter is jsonb containment — extra facet guards simply
|
|
@@ -613,7 +614,8 @@ async function resolveByMetadataAtomic(key, value, userId, resolverPayload, meta
|
|
|
613
614
|
const allRoles = writeAllRoles ?? null;
|
|
614
615
|
const selfRoles = writeSelfRoles ?? null;
|
|
615
616
|
const { rows } = await pool.query(sql_1.RESOLVE_BY_METADATA_ATOMIC, [filter, userId, payloadJson, metaPatch, allRoles, selfRoles,
|
|
616
|
-
enforcingRoles?.length ? enforcingRoles : null, assertId ?? null
|
|
617
|
+
enforcingRoles?.length ? enforcingRoles : null, assertId ?? null,
|
|
618
|
+
availability && availability !== scan_code_1.SCAN_AVAILABILITY.ANY ? availability : null]);
|
|
617
619
|
if (rows.length === 0)
|
|
618
620
|
return { outcome: 'not_found' };
|
|
619
621
|
const row = rows[0];
|
|
@@ -47,6 +47,14 @@ function buildFacetWhere(q, params, opts = {}) {
|
|
|
47
47
|
params.push(q.roles);
|
|
48
48
|
clauses.push(`role = ANY($${params.length}::text[])`);
|
|
49
49
|
}
|
|
50
|
+
if (q.types && q.types.length) {
|
|
51
|
+
params.push(q.types);
|
|
52
|
+
clauses.push(`type = ANY($${params.length}::text[])`);
|
|
53
|
+
}
|
|
54
|
+
if (q.subtypes && q.subtypes.length) {
|
|
55
|
+
params.push(q.subtypes);
|
|
56
|
+
clauses.push(`subtype = ANY($${params.length}::text[])`);
|
|
57
|
+
}
|
|
50
58
|
if (q.status) {
|
|
51
59
|
params.push(q.status);
|
|
52
60
|
clauses.push(`status = $${params.length}`);
|
|
@@ -59,7 +59,9 @@ export declare function searchEscalationsQuery(orderBy: string): string;
|
|
|
59
59
|
* $1 = metadata filter (jsonb), $2 = userId, $3 = resolver_payload (jsonb),
|
|
60
60
|
* $4 = metadata patch (jsonb, nullable), $5 = write_all roles (text[], null = global /
|
|
61
61
|
* no filter), $6 = write_self roles (text[], nullable), $7 = enforcing roles
|
|
62
|
-
* (text[], null = none), $8 = assert id (uuid, nullable)
|
|
62
|
+
* (text[], null = none), $8 = assert id (uuid, nullable), $9 = claim state
|
|
63
|
+
* ('mine' | 'available' | 'claimed', null = any). 'mine' is a live claim held by
|
|
64
|
+
* $2 and picks the most recently claimed row first.
|
|
63
65
|
*
|
|
64
66
|
* Write-scope is folded into the same FOR UPDATE statement (no TOCTOU): the row
|
|
65
67
|
* is resolvable if the caller has global access ($5 NULL), or the row's role is in
|
|
@@ -75,7 +77,7 @@ export declare function searchEscalationsQuery(orderBy: string): string;
|
|
|
75
77
|
* resolution surfaces as zero rows → the caller's conflict handling). This is
|
|
76
78
|
* the same pick-then-guarded-finish shape the signal outcomes already use.
|
|
77
79
|
*/
|
|
78
|
-
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";
|
|
80
|
+
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 AND (\n $9::text IS NULL\n OR ($9 = 'mine' AND assigned_to = $2 AND assigned_until > NOW())\n OR ($9 = 'available' AND (assigned_to IS NULL OR assigned_until IS NULL OR assigned_until <= NOW()))\n OR ($9 = 'claimed' AND assigned_to IS NOT NULL AND assigned_until > NOW())\n )\n ORDER BY CASE WHEN $9 = 'mine' THEN claimed_at END DESC NULLS LAST, 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";
|
|
79
81
|
/**
|
|
80
82
|
* Live counts — pending, active claims, and priority (past-threshold) per role.
|
|
81
83
|
*
|
|
@@ -167,7 +167,9 @@ function searchEscalationsQuery(orderBy) {
|
|
|
167
167
|
* $1 = metadata filter (jsonb), $2 = userId, $3 = resolver_payload (jsonb),
|
|
168
168
|
* $4 = metadata patch (jsonb, nullable), $5 = write_all roles (text[], null = global /
|
|
169
169
|
* no filter), $6 = write_self roles (text[], nullable), $7 = enforcing roles
|
|
170
|
-
* (text[], null = none), $8 = assert id (uuid, nullable)
|
|
170
|
+
* (text[], null = none), $8 = assert id (uuid, nullable), $9 = claim state
|
|
171
|
+
* ('mine' | 'available' | 'claimed', null = any). 'mine' is a live claim held by
|
|
172
|
+
* $2 and picks the most recently claimed row first.
|
|
171
173
|
*
|
|
172
174
|
* Write-scope is folded into the same FOR UPDATE statement (no TOCTOU): the row
|
|
173
175
|
* is resolvable if the caller has global access ($5 NULL), or the row's role is in
|
|
@@ -195,7 +197,13 @@ WITH target AS MATERIALIZED (
|
|
|
195
197
|
OR (role = ANY($6::text[]) AND assigned_to = $2)
|
|
196
198
|
)
|
|
197
199
|
AND ($8::uuid IS NULL OR id = $8::uuid)
|
|
198
|
-
|
|
200
|
+
AND (
|
|
201
|
+
$9::text IS NULL
|
|
202
|
+
OR ($9 = 'mine' AND assigned_to = $2 AND assigned_until > NOW())
|
|
203
|
+
OR ($9 = 'available' AND (assigned_to IS NULL OR assigned_until IS NULL OR assigned_until <= NOW()))
|
|
204
|
+
OR ($9 = 'claimed' AND assigned_to IS NOT NULL AND assigned_until > NOW())
|
|
205
|
+
)
|
|
206
|
+
ORDER BY CASE WHEN $9 = 'mine' THEN claimed_at END DESC NULLS LAST, priority ASC, created_at ASC
|
|
199
207
|
LIMIT 1
|
|
200
208
|
FOR UPDATE
|
|
201
209
|
),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExecutionExportOptions, WorkflowExecution } from '@hotmeshio/hotmesh/build/types/exporter';
|
|
2
2
|
import type { LTExportOptions, LTWorkflowExport } from '../../types';
|
|
3
|
+
import { type WorkflowState } from '../workflow-state';
|
|
3
4
|
import type { JobListParams, JobListResult } from './types';
|
|
4
5
|
/**
|
|
5
6
|
* Export the full workflow state for a given workflow (raw HotMesh format).
|
|
@@ -9,12 +10,14 @@ import type { JobListParams, JobListResult } from './types';
|
|
|
9
10
|
*/
|
|
10
11
|
export declare function exportWorkflow(workflowId: string, taskQueue: string, workflowName: string, options?: LTExportOptions): Promise<LTWorkflowExport>;
|
|
11
12
|
/**
|
|
12
|
-
* Return
|
|
13
|
-
* 0
|
|
13
|
+
* Return the status semaphore for a workflow (above 0 running, 0 closed,
|
|
14
|
+
* below 0 terminated) and the state it implies.
|
|
14
15
|
*/
|
|
15
16
|
export declare function getWorkflowStatus(workflowId: string, taskQueue: string, workflowName: string): Promise<{
|
|
16
17
|
workflow_id: string;
|
|
17
18
|
status: number;
|
|
19
|
+
state: WorkflowState;
|
|
20
|
+
terminated: boolean;
|
|
18
21
|
}>;
|
|
19
22
|
/**
|
|
20
23
|
* Export workflow state as a structured execution event history.
|
|
@@ -27,7 +30,9 @@ export declare function exportWorkflowExecution(workflowId: string, taskQueue: s
|
|
|
27
30
|
/** The input/output envelope pair plus the derived run status. */
|
|
28
31
|
export interface WorkflowEnvelopes {
|
|
29
32
|
workflow_id: string;
|
|
30
|
-
status:
|
|
33
|
+
status: WorkflowState;
|
|
34
|
+
/** Present and true when an interrupt ended the run. */
|
|
35
|
+
terminated?: boolean;
|
|
31
36
|
/** The workflow's input — the single LTEnvelope for one-arg workflows, else the args array. */
|
|
32
37
|
input: unknown;
|
|
33
38
|
/** The workflow's return envelope, or null while it is still running or when it failed. */
|
|
@@ -10,6 +10,7 @@ const db_1 = require("../../lib/db");
|
|
|
10
10
|
const hotmesh_utils_1 = require("../hotmesh-utils");
|
|
11
11
|
const client_1 = require("./client");
|
|
12
12
|
const post_process_1 = require("./post-process");
|
|
13
|
+
const workflow_state_1 = require("../workflow-state");
|
|
13
14
|
/** Error thrown when a workflow job is not found (expired or never existed). */
|
|
14
15
|
class WorkflowNotFoundError extends Error {
|
|
15
16
|
constructor(workflowId) {
|
|
@@ -44,14 +45,14 @@ async function exportWorkflow(workflowId, taskQueue, workflowName, options) {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
|
-
* Return
|
|
48
|
-
* 0
|
|
48
|
+
* Return the status semaphore for a workflow (above 0 running, 0 closed,
|
|
49
|
+
* below 0 terminated) and the state it implies.
|
|
49
50
|
*/
|
|
50
51
|
async function getWorkflowStatus(workflowId, taskQueue, workflowName) {
|
|
51
52
|
try {
|
|
52
53
|
const handle = await (0, client_1.getHandle)(taskQueue, workflowName, workflowId);
|
|
53
54
|
const status = await handle.status();
|
|
54
|
-
return { workflow_id: workflowId, status };
|
|
55
|
+
return { workflow_id: workflowId, status, state: (0, workflow_state_1.workflowStateFromStatus)(status), terminated: (0, workflow_state_1.isTerminated)(status) };
|
|
55
56
|
}
|
|
56
57
|
catch {
|
|
57
58
|
throw new WorkflowNotFoundError(workflowId);
|
|
@@ -97,8 +98,8 @@ async function getWorkflowEnvelopes(workflowId, taskQueue, workflowName) {
|
|
|
97
98
|
catch {
|
|
98
99
|
throw new WorkflowNotFoundError(workflowId);
|
|
99
100
|
}
|
|
100
|
-
const [
|
|
101
|
-
|
|
101
|
+
const [reading, args] = await Promise.all([
|
|
102
|
+
(0, workflow_state_1.readWorkflowState)(handle),
|
|
102
103
|
handle.input().catch(() => undefined),
|
|
103
104
|
]).catch(() => {
|
|
104
105
|
throw new WorkflowNotFoundError(workflowId);
|
|
@@ -106,28 +107,21 @@ async function getWorkflowEnvelopes(workflowId, taskQueue, workflowName) {
|
|
|
106
107
|
// Long-tail workflows take a single LTEnvelope argument — unwrap it;
|
|
107
108
|
// multi-arg workflows keep the args array verbatim.
|
|
108
109
|
const input = Array.isArray(args) && args.length === 1 ? args[0] : args ?? null;
|
|
109
|
-
if (
|
|
110
|
-
return { workflow_id: workflowId, status:
|
|
110
|
+
if (reading.state === workflow_state_1.WORKFLOW_STATES.RUNNING) {
|
|
111
|
+
return { workflow_id: workflowId, status: reading.state, input, output: null };
|
|
111
112
|
}
|
|
112
|
-
|
|
113
|
-
const output = await handle.output();
|
|
114
|
-
return {
|
|
115
|
-
workflow_id: workflowId,
|
|
116
|
-
status: statusCode === 0 ? 'completed' : 'failed',
|
|
117
|
-
input,
|
|
118
|
-
output: output ?? null,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
catch (err) {
|
|
122
|
-
// output() throws the workflow's own error for failed runs — that IS the outcome.
|
|
113
|
+
if (reading.state === workflow_state_1.WORKFLOW_STATES.FAILED) {
|
|
123
114
|
return {
|
|
124
115
|
workflow_id: workflowId,
|
|
125
|
-
status:
|
|
116
|
+
status: reading.state,
|
|
117
|
+
...(reading.terminated ? { terminated: true } : {}),
|
|
126
118
|
input,
|
|
127
119
|
output: null,
|
|
128
|
-
error:
|
|
120
|
+
...(reading.error ? { error: reading.error } : {}),
|
|
129
121
|
};
|
|
130
122
|
}
|
|
123
|
+
const output = await handle.output().catch(() => null);
|
|
124
|
+
return { workflow_id: workflowId, status: reading.state, input, output: output ?? null };
|
|
131
125
|
}
|
|
132
126
|
/**
|
|
133
127
|
* Return the current job state of a workflow.
|
|
@@ -225,7 +219,7 @@ async function listJobs(app_id, params) {
|
|
|
225
219
|
const jobs = dataResult.rows.map((row) => ({
|
|
226
220
|
workflow_id: row.key.replace(keyPrefix, ''),
|
|
227
221
|
entity: row.entity,
|
|
228
|
-
status: (
|
|
222
|
+
status: (0, workflow_state_1.workflowStateFromStatus)(row.status),
|
|
229
223
|
is_live: row.is_live,
|
|
230
224
|
created_at: row.created_at,
|
|
231
225
|
updated_at: row.updated_at,
|
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
import type { LTApiAuth } from '../../types/sdk';
|
|
2
|
+
/** What the client needs to know about a grant after a request touched it. */
|
|
3
|
+
export interface ActingGrantState {
|
|
4
|
+
/** True when this request spent a use. */
|
|
5
|
+
consumed: boolean;
|
|
6
|
+
/** Uses left; null = bounded only by TTL (or bound to one subject). */
|
|
7
|
+
remaining: number | null;
|
|
8
|
+
/** True once the grant is bound to one subject. */
|
|
9
|
+
bound: boolean;
|
|
10
|
+
}
|
|
2
11
|
/** The acting-auth resolution result: an auth to act as, or the loud reason not to. */
|
|
3
12
|
export type ActingAuthResult = {
|
|
4
13
|
ok: true;
|
|
5
14
|
auth: LTApiAuth;
|
|
15
|
+
grant: ActingGrantState;
|
|
6
16
|
} | {
|
|
7
17
|
ok: false;
|
|
8
18
|
error: string;
|
|
9
19
|
};
|
|
20
|
+
export declare const ACTING_ERRORS: {
|
|
21
|
+
readonly NOT_A_GRANT: "actingToken is not an acting-identity grant";
|
|
22
|
+
readonly EXPIRED: "acting identity expired — scan your badge again";
|
|
23
|
+
readonly INACTIVE: "acting identity is no longer an active user";
|
|
24
|
+
readonly OTHER_SUBJECT: "this badge already acted on another item; scan your badge again";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Read a supplied acting grant without spending it. A token that fails
|
|
28
|
+
* (wrong label, expired, exhausted, or a vanished user) is a terminal error,
|
|
29
|
+
* never a silent fall-back to the session identity: that would misattribute
|
|
30
|
+
* whatever follows.
|
|
31
|
+
*/
|
|
32
|
+
export declare function peekActingAuth(actingToken: string): Promise<ActingAuthResult>;
|
|
10
33
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* terminal error, never a silent fall-back to the session identity: that
|
|
14
|
-
* would misattribute whatever follows.
|
|
34
|
+
* Spend one use of the grant for an act. `ref` names the subject the act
|
|
35
|
+
* lands on; a subject-scoped grant binds to it on first spend.
|
|
15
36
|
*/
|
|
37
|
+
export declare function consumeActingGrant(actingToken: string, ref?: string | null): Promise<ActingAuthResult>;
|
|
38
|
+
/** Return a use whose act missed. `unbind` when that spend bound the grant. */
|
|
39
|
+
export declare function refundActingGrant(actingToken: string, unbind: boolean): Promise<void>;
|
|
40
|
+
/** Spend the grant up front: the escalation work routes always act. */
|
|
16
41
|
export declare function resolveActingAuth(actingToken: string): Promise<ActingAuthResult>;
|