@hotmeshio/long-tail 0.22.1 → 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.js +38 -19
- 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 +16 -10
- 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 +1 -21
- package/build/api/scan-codes/verbs.js +26 -115
- package/build/index.d.ts +1 -0
- package/build/index.js +8 -2
- package/build/lib/db/schemas/037_scan_gtin_and_subject_grants.sql +27 -0
- 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/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/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 +94 -18
- package/build/services/scan-code/write.d.ts +1 -0
- package/build/services/scan-code/write.js +9 -3
- 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/system/mcp-servers/admin/scan-codes.js +10 -4
- package/build/system/mcp-servers/admin/schemas.d.ts +754 -23
- package/build/system/mcp-servers/admin/schemas.js +57 -4
- package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +2 -0
- package/build/types/escalation.js +3 -1
- package/build/types/index.d.ts +2 -2
- 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} +72 -11
- 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-BbWve-Ax.js → AdminDashboard-DBW12qQt.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BbWve-Ax.js.map → AdminDashboard-DBW12qQt.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js → AgentConfigPage-CmHv8U9M.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js.map → AgentConfigPage-CmHv8U9M.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js → AgentDetailPage-D1scIbz-.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js.map → AgentDetailPage-D1scIbz-.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js → AgentsPage-BA_ai9HJ.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js.map → AgentsPage-BA_ai9HJ.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js → AvailableEscalationsPage-C2_5aEFW.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js.map → AvailableEscalationsPage-C2_5aEFW.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-CGB16rYU.js → BotPicker-BZo4Kp4a.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CGB16rYU.js.map → BotPicker-BZo4Kp4a.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js → BulkAssignModal-BFhyxY2T.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js.map → BulkAssignModal-BFhyxY2T.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-CvOX6vAc.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-BxadotXn.js.map → CapabilitiesPage-CvOX6vAc.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js → CollapsibleSection-GCJsV9Oq.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js.map → CollapsibleSection-GCJsV9Oq.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js → ConfirmDeleteModal-CAgYLcef.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js.map → ConfirmDeleteModal-CAgYLcef.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-Dik2z0M_.js +2 -0
- package/dashboard/dist/assets/{CountdownTimer-CI_JOAvk.js.map → CountdownTimer-Dik2z0M_.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js → CredentialsPage-twd2xCOW.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js.map → CredentialsPage-twd2xCOW.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js → CronLabel-DdnIuudX.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js.map → CronLabel-DdnIuudX.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js → ElapsedCell-DCctVv5R.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js.map → ElapsedCell-DCctVv5R.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js → EntityTimelinePanel-CMnskyWv.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js.map → EntityTimelinePanel-CMnskyWv.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js → EscalationListSchemaPage-VfCn6WDb.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js.map → EscalationListSchemaPage-VfCn6WDb.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js → EscalationListView-CGQZxcC-.js} +2 -2
- package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js.map → EscalationListView-CGQZxcC-.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js → EscalationSchemaPage-BX0tx-PM.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js.map → EscalationSchemaPage-BX0tx-PM.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js → EscalationTimeline-DKoSM56J.js} +2 -2
- package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js.map → EscalationTimeline-DKoSM56J.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js → EscalationTitleSelect-DWGLBOmS.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js.map → EscalationTitleSelect-DWGLBOmS.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js → EscalationsOverview-C2XoguaA.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js.map → EscalationsOverview-C2XoguaA.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DSHqKyX2.js → EventTable-CBUWq7--.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DSHqKyX2.js.map → EventTable-CBUWq7--.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js → FilterBar-8IdbleZ9.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.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-ChqqGkro.js → GraphInvokePage-CUvoPzsW.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-ChqqGkro.js.map → GraphInvokePage-CUvoPzsW.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-ByKesG8w.js → HomePage-BP7v9GLJ.js} +2 -2
- package/dashboard/dist/assets/{HomePage-ByKesG8w.js.map → HomePage-BP7v9GLJ.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js → ListToolbar-Cnacuwoy.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js.map → ListToolbar-Cnacuwoy.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CVe13tEv.js → McpOverview-C2JoNoDA.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CVe13tEv.js.map → McpOverview-C2JoNoDA.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js → McpQueryDetailPage-C_nih0w-.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js.map → McpQueryDetailPage-C_nih0w-.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js → McpQueryPage-U_wNXow2.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js.map → McpQueryPage-U_wNXow2.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js → McpRunDetailPage-DtKoJq6J.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js.map → McpRunDetailPage-DtKoJq6J.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js → McpRunsPage-CnYtfGhf.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js.map → McpRunsPage-CnYtfGhf.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js → OperationsPage-C7hupIer.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js.map → OperationsPage-C7hupIer.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js → OperatorDashboard-fVuLn2D5.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js.map → OperatorDashboard-fVuLn2D5.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js → PersonaDetailPage-C-4o8lPw.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js.map → PersonaDetailPage-C-4o8lPw.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js → PersonasPage-BL1FwLmv.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js.map → PersonasPage-BL1FwLmv.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js → PortalPage-tJG5sgb1.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js.map → PortalPage-tJG5sgb1.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js → ProcessDetailPage-Dz_jY4Yt.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js.map → ProcessDetailPage-Dz_jY4Yt.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js → ProcessesListPage-Cbn9cter.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.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/{RolesPage-0QJOBSzF.js → RolesPage-NwmMvZFa.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js.map → RolesPage-NwmMvZFa.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js → RunAsSelector-tgEooTyU.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.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/{StickyPagination-BSUyf5ja.js → StickyPagination-CsTI_gvJ.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js.map → StickyPagination-CsTI_gvJ.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js → StreamMessageDetail-auRlvjTh.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js.map → StreamMessageDetail-auRlvjTh.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js → SwimlaneTimeline-BLoVHYAd.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js.map → SwimlaneTimeline-BLoVHYAd.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js → TaskDetailPage-BPsZ1bK_.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js.map → TaskDetailPage-BPsZ1bK_.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js → TasksListPage-BNGM74yT.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js.map → TasksListPage-BNGM74yT.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js → TimeAgo-BnAHXGK7.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js.map → TimeAgo-BnAHXGK7.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js → TimestampCell-J4yae6mc.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js.map → TimestampCell-J4yae6mc.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js → ToolTestPanel-BdzzgXDu.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js.map → ToolTestPanel-BdzzgXDu.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js → TopicDetailPage-DJKg8lb7.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js.map → TopicDetailPage-DJKg8lb7.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js → TopicsPage-DQV0WxG6.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js.map → TopicsPage-DQV0WxG6.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CXsdPiMZ.js → UserName-Ct09nGh5.js} +2 -2
- package/dashboard/dist/assets/{UserName-CXsdPiMZ.js.map → UserName-Ct09nGh5.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js → WorkflowExecutionPage-B5WJOsee.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js.map → WorkflowExecutionPage-B5WJOsee.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js → WorkflowsDashboard-Hc87TRgD.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js.map → WorkflowsDashboard-Hc87TRgD.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js → WorkflowsOverview-CJQbyOj-.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js.map → WorkflowsOverview-CJQbyOj-.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js → YamlWorkflowDetailPage-BMeED677.js} +8 -8
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js.map → YamlWorkflowDetailPage-BMeED677.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js → YamlWorkflowsPage-BMMg0Id6.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js.map → YamlWorkflowsPage-BMMg0Id6.js.map} +1 -1
- package/dashboard/dist/assets/{agents-v_HH3Rji.js → agents-CdFkgFvg.js} +2 -2
- package/dashboard/dist/assets/{agents-v_HH3Rji.js.map → agents-CdFkgFvg.js.map} +1 -1
- package/dashboard/dist/assets/{bots-bwvWYrXz.js → bots-Mj3LHWWg.js} +2 -2
- package/dashboard/dist/assets/{bots-bwvWYrXz.js.map → bots-Mj3LHWWg.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js → capabilities-Dw1ObK2-.js} +2 -2
- package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js.map → capabilities-Dw1ObK2-.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js → controlplane-DcNE1APv.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js.map → controlplane-DcNE1APv.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js → escalation-columns-D364Trpy.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js.map → escalation-columns-D364Trpy.js.map} +1 -1
- package/dashboard/dist/assets/{index-IJmtbuLh.js → index-B3veJ698.js} +2 -2
- package/dashboard/dist/assets/{index-IJmtbuLh.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-D2VKBMng.js → index-BRGTmoYY.js} +2 -2
- package/dashboard/dist/assets/{index-D2VKBMng.js.map → index-BRGTmoYY.js.map} +1 -1
- package/dashboard/dist/assets/{index-C4Lce2ET.js → index-Bd6-KmBE.js} +3 -3
- package/dashboard/dist/assets/{index-C4Lce2ET.js.map → index-Bd6-KmBE.js.map} +1 -1
- package/dashboard/dist/assets/{index-CcuvGdvf.js → index-BiVce3n0.js} +2 -2
- package/dashboard/dist/assets/{index-CcuvGdvf.js.map → index-BiVce3n0.js.map} +1 -1
- package/dashboard/dist/assets/{index-D6pBLZFu.js → index-BmNAVd4s.js} +2 -2
- package/dashboard/dist/assets/{index-D6pBLZFu.js.map → index-BmNAVd4s.js.map} +1 -1
- package/dashboard/dist/assets/{index-CjenRVX_.js → index-Bq5XNEzD.js} +2 -2
- package/dashboard/dist/assets/{index-CjenRVX_.js.map → index-Bq5XNEzD.js.map} +1 -1
- package/dashboard/dist/assets/{index-CzjUgFt_.js → index-DPStdq4T.js} +2 -2
- package/dashboard/dist/assets/{index-CzjUgFt_.js.map → index-DPStdq4T.js.map} +1 -1
- package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
- package/dashboard/dist/assets/{index-C3WutFpT.js → index-DkcI4V_H.js} +2 -2
- package/dashboard/dist/assets/{index-C3WutFpT.js.map → index-DkcI4V_H.js.map} +1 -1
- package/dashboard/dist/assets/{index-2tzsxFat.js → index-Dyotfa_k.js} +2 -2
- package/dashboard/dist/assets/{index-2tzsxFat.js.map → index-Dyotfa_k.js.map} +1 -1
- package/dashboard/dist/assets/{index-C_ISDOWJ.js → index-MDD4JYtu.js} +2 -2
- package/dashboard/dist/assets/{index-C_ISDOWJ.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-BLB77tc8.js → index-eDm6cz0F.js} +2 -2
- package/dashboard/dist/assets/{index-BLB77tc8.js.map → index-eDm6cz0F.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-D1YP2NzS.js → knowledge-Bafewjxk.js} +2 -2
- package/dashboard/dist/assets/{knowledge-D1YP2NzS.js.map → knowledge-Bafewjxk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js → mcp-query-BzTtIG90.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js.map → mcp-query-BzTtIG90.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Bb5psC61.js → mcp-vLIutbnc.js} +2 -2
- package/dashboard/dist/assets/{mcp-Bb5psC61.js.map → mcp-vLIutbnc.js.map} +1 -1
- package/dashboard/dist/assets/{personas-CDndbkp4.js → personas-WD40EDS_.js} +2 -2
- package/dashboard/dist/assets/{personas-CDndbkp4.js.map → personas-WD40EDS_.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js → pipelines-DFwULWs3.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js.map → pipelines-DFwULWs3.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BlpDsWCy.js → tasks-La_-WAUn.js} +2 -2
- package/dashboard/dist/assets/{tasks-BlpDsWCy.js.map → tasks-La_-WAUn.js.map} +1 -1
- package/dashboard/dist/assets/{topics-C0YaR9fu.js → topics-CzYMlvqm.js} +2 -2
- package/dashboard/dist/assets/{topics-C0YaR9fu.js.map → topics-CzYMlvqm.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js → useDebouncedValue-C0FQyANW.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js.map → useDebouncedValue-C0FQyANW.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js → useNamespace-WW_XjAb3.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js.map → useNamespace-WW_XjAb3.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js → useYamlActivityEvents-B3YxPeFt.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js.map → useYamlActivityEvents-B3YxPeFt.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js → yaml-workflows-COHOjdhF.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js.map → yaml-workflows-COHOjdhF.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/dashboard.md +1 -1
- package/docs/hitl/x-lt-scan.md +51 -0
- package/docs/hitl-guide.md +2 -0
- package/docs/scan-codes.md +221 -21
- package/package.json +1 -1
- package/build/types/scan-code.d.ts +0 -317
- package/dashboard/dist/assets/CapabilitiesPage-BxadotXn.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-CI_JOAvk.js +0 -2
- package/dashboard/dist/assets/ResolverForm-BVG8X0sS.js +0 -8
- package/dashboard/dist/assets/ResolverForm-BVG8X0sS.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-KCXDqoJz.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-KCXDqoJz.js.map +0 -1
- package/dashboard/dist/assets/ScanCodesPage-CUhCz-Yr.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-CUhCz-Yr.js.map +0 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-qzXKNqJK.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-qzXKNqJK.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-D8e8cG3t.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-D8e8cG3t.js.map +0 -1
- package/dashboard/dist/assets/index-CT-FN6CW.js +0 -3
- package/dashboard/dist/assets/index-CT-FN6CW.js.map +0 -1
- package/dashboard/dist/assets/index-Dh8MJl3L.css +0 -1
- package/dashboard/dist/assets/index-N71QQ3J5.js +0 -67
- package/dashboard/dist/assets/index-N71QQ3J5.js.map +0 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ScanExecuteResponse, type ScanStep } from '../../types';
|
|
2
|
+
import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
3
|
+
import { type GrantLedger, type StepContext } from './context';
|
|
4
|
+
export type PeekResult = {
|
|
5
|
+
ok: true;
|
|
6
|
+
auth: LTApiAuth;
|
|
7
|
+
grant: GrantLedger;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: string;
|
|
11
|
+
};
|
|
12
|
+
/** Read the grant without spending it. */
|
|
13
|
+
export declare function peekGrant(token: string): Promise<PeekResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Spend the request's grant before a write. Returns null when the act may
|
|
16
|
+
* proceed (spent now, spent earlier in this request, or no grant rides it),
|
|
17
|
+
* and the not-primed result when the grant cannot cover this act. `ref` is
|
|
18
|
+
* the held subject the act lands on.
|
|
19
|
+
*/
|
|
20
|
+
export declare function spendGrant(ctx: StepContext, ref?: string | null): Promise<LTApiResult<ScanExecuteResponse> | null>;
|
|
21
|
+
/** The step's identity requirement, checked at the moment it is about to act. */
|
|
22
|
+
export declare function identityGate(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Close the request's books on the grant: refund a spend whose act did not
|
|
25
|
+
* land, and report the grant's state for the client to keep or retire.
|
|
26
|
+
*/
|
|
27
|
+
export declare function settleGrant(ctx: StepContext, result: LTApiResult<ScanExecuteResponse> | null): Promise<ScanExecuteResponse['acting'] | undefined>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.peekGrant = peekGrant;
|
|
4
|
+
exports.spendGrant = spendGrant;
|
|
5
|
+
exports.identityGate = identityGate;
|
|
6
|
+
exports.settleGrant = settleGrant;
|
|
7
|
+
const acting_identity_1 = require("../../services/iam/acting-identity");
|
|
8
|
+
const types_1 = require("../../types");
|
|
9
|
+
const context_1 = require("./context");
|
|
10
|
+
const identity_1 = require("./identity");
|
|
11
|
+
/** Read the grant without spending it. */
|
|
12
|
+
async function peekGrant(token) {
|
|
13
|
+
const peeked = await (0, acting_identity_1.peekActingAuth)(token);
|
|
14
|
+
if (!peeked.ok)
|
|
15
|
+
return peeked;
|
|
16
|
+
return {
|
|
17
|
+
ok: true,
|
|
18
|
+
auth: peeked.auth,
|
|
19
|
+
grant: { token, peeked: { remaining: peeked.grant.remaining, bound: peeked.grant.bound }, spent: null },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Spend the request's grant before a write. Returns null when the act may
|
|
24
|
+
* proceed (spent now, spent earlier in this request, or no grant rides it),
|
|
25
|
+
* and the not-primed result when the grant cannot cover this act. `ref` is
|
|
26
|
+
* the held subject the act lands on.
|
|
27
|
+
*/
|
|
28
|
+
async function spendGrant(ctx, ref = ctx.subject?.row.id ?? null) {
|
|
29
|
+
const grant = ctx.grant;
|
|
30
|
+
if (!grant || grant.spent)
|
|
31
|
+
return null;
|
|
32
|
+
const consumed = await (0, acting_identity_1.consumeActingGrant)(grant.token, ref);
|
|
33
|
+
if (!consumed.ok)
|
|
34
|
+
return (0, context_1.notPrimed)(ctx, consumed.error);
|
|
35
|
+
grant.spent = { remaining: consumed.grant.remaining, bound: consumed.grant.bound };
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/** The step's identity requirement, checked at the moment it is about to act. */
|
|
39
|
+
async function identityGate(step, ctx) {
|
|
40
|
+
if (!step.requireActingIdentity || (await (0, identity_1.actingIdentitySatisfied)(step, ctx)))
|
|
41
|
+
return null;
|
|
42
|
+
return (0, context_1.notPrimed)(ctx);
|
|
43
|
+
}
|
|
44
|
+
/** True when the result is a write that landed. */
|
|
45
|
+
function landed(result) {
|
|
46
|
+
const data = result?.data;
|
|
47
|
+
return !!data && data.outcome === types_1.SCAN_OUTCOMES.EXECUTED
|
|
48
|
+
&& !!data.verb && types_1.SCAN_MUTATING_VERBS.includes(data.verb) && !data.already;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Close the request's books on the grant: refund a spend whose act did not
|
|
52
|
+
* land, and report the grant's state for the client to keep or retire.
|
|
53
|
+
*/
|
|
54
|
+
async function settleGrant(ctx, result) {
|
|
55
|
+
const grant = ctx.grant;
|
|
56
|
+
if (!grant)
|
|
57
|
+
return undefined;
|
|
58
|
+
if (grant.spent && !landed(result)) {
|
|
59
|
+
// Spending a bound grant cost nothing; spending an unbound one counted
|
|
60
|
+
// a use and may have bound it, so both come back.
|
|
61
|
+
if (!grant.peeked.bound)
|
|
62
|
+
await (0, acting_identity_1.refundActingGrant)(grant.token, grant.spent.bound);
|
|
63
|
+
grant.spent = null;
|
|
64
|
+
}
|
|
65
|
+
const state = grant.spent ?? grant.peeked;
|
|
66
|
+
return { consumed: !!grant.spent, remaining: state.remaining, bound: state.bound };
|
|
67
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type LTEscalationRecord, type ScanExecuteResponse, type ScanStep } from '../../types';
|
|
2
|
+
import type { LTApiResult } from '../../types/sdk';
|
|
3
|
+
import { type StepContext } from './context';
|
|
4
|
+
/**
|
|
5
|
+
* HOLD: locate the row and hand the station a subject to hold. The next
|
|
6
|
+
* scans (the badge, then the container) act on it. Writes nothing and spends
|
|
7
|
+
* no badge use. A live claim by someone else is reported, not refused: the
|
|
8
|
+
* bench says whose it is, and the act decides.
|
|
9
|
+
*/
|
|
10
|
+
export declare function holdStep(step: ScanStep, ctx: StepContext, located?: LTEscalationRecord): Promise<LTApiResult<ScanExecuteResponse> | null>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.holdStep = holdStep;
|
|
37
|
+
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
38
|
+
const types_1 = require("../../types");
|
|
39
|
+
const context_1 = require("./context");
|
|
40
|
+
const locate_1 = require("./locate");
|
|
41
|
+
const subject_1 = require("./subject");
|
|
42
|
+
/**
|
|
43
|
+
* HOLD: locate the row and hand the station a subject to hold. The next
|
|
44
|
+
* scans (the badge, then the container) act on it. Writes nothing and spends
|
|
45
|
+
* no badge use. A live claim by someone else is reported, not refused: the
|
|
46
|
+
* bench says whose it is, and the act decides.
|
|
47
|
+
*/
|
|
48
|
+
async function holdStep(step, ctx, located) {
|
|
49
|
+
const row = located ?? (await (0, locate_1.locateForStep)(step, ctx, 1))?.escalations[0];
|
|
50
|
+
if (!row)
|
|
51
|
+
return null;
|
|
52
|
+
return {
|
|
53
|
+
status: 200,
|
|
54
|
+
data: {
|
|
55
|
+
outcome: types_1.SCAN_OUTCOMES.HELD,
|
|
56
|
+
verb: step.verb,
|
|
57
|
+
escalation: row,
|
|
58
|
+
subject: await heldSubject(step, ctx, row),
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function heldSubject(step, ctx, row) {
|
|
63
|
+
const hold = step.params?.hold ?? {};
|
|
64
|
+
const tpl = { ...(0, context_1.templateContext)(ctx), item: row.metadata ?? {} };
|
|
65
|
+
const ttl = hold.ttlSeconds ?? types_1.SCAN_HOLD_TTL_DEFAULT_SECONDS;
|
|
66
|
+
const claimant = await (0, subject_1.claimedByOther)(row, ctx.acting ? ctx.auth.userId : null);
|
|
67
|
+
return {
|
|
68
|
+
code: ctx.rawCode ?? holdCode(ctx),
|
|
69
|
+
escalationId: row.id,
|
|
70
|
+
label: scanCodeService.renderScanCopy(hold.label ?? types_1.SCAN_TEMPLATE_TOKENS.TARGET, tpl),
|
|
71
|
+
...optionalCopy('headline', hold.headline, tpl),
|
|
72
|
+
...optionalCopy('subline', hold.subline, tpl),
|
|
73
|
+
expiresAt: new Date(Date.now() + ttl * 1000).toISOString(),
|
|
74
|
+
...(hold.expect ? {
|
|
75
|
+
expect: {
|
|
76
|
+
schemes: hold.expect.schemes,
|
|
77
|
+
...(hold.expect.prompt ? { prompt: scanCodeService.renderScanCopy(hold.expect.prompt, tpl) } : {}),
|
|
78
|
+
},
|
|
79
|
+
} : {}),
|
|
80
|
+
...(claimant ? { claimedBy: claimant } : {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** The canonical code for the held row, as the station would scan it. */
|
|
84
|
+
function holdCode(ctx) {
|
|
85
|
+
const { scheme, parsed } = ctx;
|
|
86
|
+
if (scheme.encoding === 'delimited') {
|
|
87
|
+
const d = scheme.delimiter;
|
|
88
|
+
return `${parsed.version}${d}${parsed.category}${d}${parsed.target}`;
|
|
89
|
+
}
|
|
90
|
+
return `${parsed.version}${parsed.category}${parsed.target}`;
|
|
91
|
+
}
|
|
92
|
+
/** A rendered line, or nothing when the template is absent or renders empty. */
|
|
93
|
+
function optionalCopy(key, template, tpl) {
|
|
94
|
+
if (!template)
|
|
95
|
+
return {};
|
|
96
|
+
const text = scanCodeService.renderScanCopy(template, tpl).trim();
|
|
97
|
+
return text ? { [key]: text } : {};
|
|
98
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { type ParsedScanCode, type ScanExecuteResponse, type ScanRule, type ScanScheme, type ScanStep } from '../../types';
|
|
2
2
|
import type { LTApiResult } from '../../types/sdk';
|
|
3
3
|
import type { StepContext } from './context';
|
|
4
|
-
export { resolveActingAuth, type ActingAuthResult } from '../../services/iam/acting-identity';
|
|
4
|
+
export { resolveActingAuth, peekActingAuth, type ActingAuthResult } from '../../services/iam/acting-identity';
|
|
5
5
|
/**
|
|
6
6
|
* Resolve an identity scan: badge → user → minted acting grant.
|
|
7
7
|
* Identity schemes never walk steps; the rule's fallback is the
|
|
8
8
|
* unknown-badge screen.
|
|
9
9
|
*/
|
|
10
|
-
export declare function executeIdentityScan(parsed: ParsedScanCode, scheme: ScanScheme, rule: ScanRule, previousActingToken?: string
|
|
10
|
+
export declare function executeIdentityScan(parsed: ParsedScanCode, scheme: ScanScheme, rule: ScanRule, previousActingToken?: string, station?: {
|
|
11
|
+
userId: string;
|
|
12
|
+
stationRole?: string;
|
|
13
|
+
}): Promise<LTApiResult<ScanExecuteResponse>>;
|
|
11
14
|
/**
|
|
12
15
|
* The identity pre-condition's satisfaction test. A primed grant always
|
|
13
16
|
* satisfies; without one, the authenticated user satisfies only when their
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.resolveActingAuth = void 0;
|
|
36
|
+
exports.peekActingAuth = exports.resolveActingAuth = void 0;
|
|
37
37
|
exports.executeIdentityScan = executeIdentityScan;
|
|
38
38
|
exports.actingIdentitySatisfied = actingIdentitySatisfied;
|
|
39
39
|
const userService = __importStar(require("../../services/user"));
|
|
@@ -41,8 +41,10 @@ const ephemeral_1 = require("../../services/iam/ephemeral");
|
|
|
41
41
|
const metadata_1 = require("../escalations/metadata");
|
|
42
42
|
const helpers_1 = require("../escalations/helpers");
|
|
43
43
|
const types_1 = require("../../types");
|
|
44
|
+
const badge_policy_1 = require("./badge-policy");
|
|
44
45
|
var acting_identity_1 = require("../../services/iam/acting-identity");
|
|
45
46
|
Object.defineProperty(exports, "resolveActingAuth", { enumerable: true, get: function () { return acting_identity_1.resolveActingAuth; } });
|
|
47
|
+
Object.defineProperty(exports, "peekActingAuth", { enumerable: true, get: function () { return acting_identity_1.peekActingAuth; } });
|
|
46
48
|
// ── Acting identity — the badge layer over the scan surface ────────────────
|
|
47
49
|
//
|
|
48
50
|
// A shared station device signs in as an ordinary read-capable account; the
|
|
@@ -58,8 +60,18 @@ Object.defineProperty(exports, "resolveActingAuth", { enumerable: true, get: fun
|
|
|
58
60
|
* Identity schemes never walk steps; the rule's fallback is the
|
|
59
61
|
* unknown-badge screen.
|
|
60
62
|
*/
|
|
61
|
-
async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
|
|
62
|
-
|
|
63
|
+
async function executeIdentityScan(parsed, scheme, rule, previousActingToken, station) {
|
|
64
|
+
// Two users bound to one badge is a configuration fault: refuse the badge
|
|
65
|
+
// and name the fault, never pick one of them.
|
|
66
|
+
let user;
|
|
67
|
+
let unknownReason = 'badge not recognized';
|
|
68
|
+
try {
|
|
69
|
+
user = await userService.getUserByMetadataValue(scheme.target_facet, parsed.target);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
user = null;
|
|
73
|
+
unknownReason = `badge is bound to more than one person: ${err.message}`;
|
|
74
|
+
}
|
|
63
75
|
if (!user) {
|
|
64
76
|
return {
|
|
65
77
|
status: 200,
|
|
@@ -68,7 +80,7 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
|
|
|
68
80
|
parsed,
|
|
69
81
|
rule: { schemeVersion: rule.scheme_version, category: rule.category, name: rule.name },
|
|
70
82
|
fallback: rule.fallback,
|
|
71
|
-
error:
|
|
83
|
+
error: unknownReason,
|
|
72
84
|
},
|
|
73
85
|
};
|
|
74
86
|
}
|
|
@@ -79,12 +91,17 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
|
|
|
79
91
|
await (0, ephemeral_1.revokeEphemeral)(prev.uuid).catch(() => { });
|
|
80
92
|
}
|
|
81
93
|
}
|
|
94
|
+
// The station decides the policy: its role's badge_grant, else the scheme's.
|
|
95
|
+
const policy = station
|
|
96
|
+
? await (0, badge_policy_1.stationGrantPolicy)(scheme, station.userId, station.stationRole)
|
|
97
|
+
: { ttlSeconds: scheme.grant_ttl_seconds ?? 0, maxUses: scheme.grant_max_uses ?? 0, scope: scheme.grant_scope ?? types_1.SCAN_GRANT_SCOPES.ACTION };
|
|
82
98
|
const uuid = await (0, ephemeral_1.storeEphemeral)(user.id, {
|
|
83
|
-
ttlSeconds:
|
|
84
|
-
maxUses:
|
|
99
|
+
ttlSeconds: policy.ttlSeconds || undefined,
|
|
100
|
+
maxUses: policy.maxUses,
|
|
85
101
|
label: types_1.ACTING_IDENTITY_LABEL,
|
|
102
|
+
bindOnUse: policy.scope === types_1.SCAN_GRANT_SCOPES.SUBJECT,
|
|
86
103
|
});
|
|
87
|
-
const expiresAt = new Date(Date.now() +
|
|
104
|
+
const expiresAt = new Date(Date.now() + policy.ttlSeconds * 1000).toISOString();
|
|
88
105
|
return {
|
|
89
106
|
status: 200,
|
|
90
107
|
data: {
|
|
@@ -94,7 +111,8 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
|
|
|
94
111
|
actor: { id: user.id, displayName: user.display_name || user.external_id },
|
|
95
112
|
actingToken: (0, ephemeral_1.formatEphemeralToken)(uuid, types_1.ACTING_IDENTITY_LABEL),
|
|
96
113
|
expiresAt,
|
|
97
|
-
maxUses:
|
|
114
|
+
maxUses: policy.maxUses,
|
|
115
|
+
grantScope: policy.scope,
|
|
98
116
|
},
|
|
99
117
|
};
|
|
100
118
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type LTEscalationRecord, type ScanScheme, type ScanSubjectRef } from '../../types';
|
|
2
|
+
import type { LTApiAuth } from '../../types/sdk';
|
|
3
|
+
import type { HeldSubject } from './context';
|
|
4
|
+
export type SubjectResult = {
|
|
5
|
+
ok: true;
|
|
6
|
+
subject: HeldSubject;
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
};
|
|
10
|
+
export declare function resolveSubject(ref: ScanSubjectRef | undefined, schemes: ScanScheme[], stationAuth: LTApiAuth): Promise<SubjectResult | null>;
|
|
11
|
+
/** Who holds a live claim on the row, when that is someone other than `actorId`. */
|
|
12
|
+
export declare function claimedByOther(row: LTEscalationRecord, actorId: string | null): Promise<{
|
|
13
|
+
id: string;
|
|
14
|
+
displayName: string;
|
|
15
|
+
} | null>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resolveSubject = resolveSubject;
|
|
37
|
+
exports.claimedByOther = claimedByOther;
|
|
38
|
+
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
39
|
+
const escalationService = __importStar(require("../../services/escalation"));
|
|
40
|
+
const userService = __importStar(require("../../services/user"));
|
|
41
|
+
const uuid_1 = require("../../lib/uuid");
|
|
42
|
+
const helpers_1 = require("../escalations/helpers");
|
|
43
|
+
const types_1 = require("../../types");
|
|
44
|
+
async function resolveSubject(ref, schemes, stationAuth) {
|
|
45
|
+
if (!ref)
|
|
46
|
+
return null;
|
|
47
|
+
if (typeof ref.code !== 'string' || !(0, uuid_1.isUuid)(ref.escalationId))
|
|
48
|
+
return { ok: false };
|
|
49
|
+
const parsed = scanCodeService.parseScanCode(ref.code, schemes);
|
|
50
|
+
if (!parsed.ok || parsed.scheme.kind !== types_1.SCAN_SCHEME_KINDS.ACTION)
|
|
51
|
+
return { ok: false };
|
|
52
|
+
const row = await escalationService.getEscalation(ref.escalationId);
|
|
53
|
+
if (!row || row.status !== 'pending')
|
|
54
|
+
return { ok: false };
|
|
55
|
+
if (await (0, helpers_1.assertReadAccess)(stationAuth.userId, row))
|
|
56
|
+
return { ok: false };
|
|
57
|
+
if (row.metadata?.[parsed.scheme.target_facet] !== parsed.parsed.target) {
|
|
58
|
+
return { ok: false };
|
|
59
|
+
}
|
|
60
|
+
return { ok: true, subject: { row, parsed: parsed.parsed, scheme: parsed.scheme, code: ref.code } };
|
|
61
|
+
}
|
|
62
|
+
/** Who holds a live claim on the row, when that is someone other than `actorId`. */
|
|
63
|
+
async function claimedByOther(row, actorId) {
|
|
64
|
+
if (!row.assigned_to || !(0, types_1.isEffectivelyClaimed)(row) || row.assigned_to === actorId)
|
|
65
|
+
return null;
|
|
66
|
+
const user = await userService.getUser(row.assigned_to);
|
|
67
|
+
return { id: row.assigned_to, displayName: user?.display_name || user?.external_id || 'another associate' };
|
|
68
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ScanExecuteResponse, type ScanStep } from '../../types';
|
|
2
|
+
import type { LTApiResult } from '../../types/sdk';
|
|
3
|
+
import { type StepContext } from './context';
|
|
4
|
+
/**
|
|
5
|
+
* Adds the scanned item to an accumulator. Two modes, one atomic write:
|
|
6
|
+
*
|
|
7
|
+
* - Item-locate (`params.accumulate.containerFacet`): the scan locates the
|
|
8
|
+
* item's own pending row through the scheme facet, reads the container
|
|
9
|
+
* facet value it carries, and adds the target to the container that shares
|
|
10
|
+
* it, writing the item row as the reciprocal in the same statement. An
|
|
11
|
+
* item with no row, or no container facet, falls through. An item whose
|
|
12
|
+
* container has closed and whose successor has not parked yet answers
|
|
13
|
+
* `no_open_container` with the item row, so the station can say "scan
|
|
14
|
+
* again" instead of showing the item with no hint.
|
|
15
|
+
* - Container-locate (no `containerFacet`): the scan locates the container
|
|
16
|
+
* by the scheme facet and adds `params.itemKey` (template).
|
|
17
|
+
*
|
|
18
|
+
* Templates may read `{claim.<facet>}` (the actor's live claim) and, in item
|
|
19
|
+
* mode, `{item.<facet>}` (the located row); an unresolvable token falls
|
|
20
|
+
* through. The write is the SDK's guarded statement; the locate only picks
|
|
21
|
+
* ids. A container already holding the item answers conflict, never a
|
|
22
|
+
* second add.
|
|
23
|
+
*/
|
|
24
|
+
export declare function accumulateStep(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.accumulateStep = accumulateStep;
|
|
37
|
+
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
38
|
+
const accumulate_1 = require("../escalations/accumulate");
|
|
39
|
+
const types_1 = require("../../types");
|
|
40
|
+
const context_1 = require("./context");
|
|
41
|
+
const grant_1 = require("./grant");
|
|
42
|
+
const locate_1 = require("./locate");
|
|
43
|
+
const verbs_subject_1 = require("./verbs-subject");
|
|
44
|
+
/**
|
|
45
|
+
* Adds the scanned item to an accumulator. Two modes, one atomic write:
|
|
46
|
+
*
|
|
47
|
+
* - Item-locate (`params.accumulate.containerFacet`): the scan locates the
|
|
48
|
+
* item's own pending row through the scheme facet, reads the container
|
|
49
|
+
* facet value it carries, and adds the target to the container that shares
|
|
50
|
+
* it, writing the item row as the reciprocal in the same statement. An
|
|
51
|
+
* item with no row, or no container facet, falls through. An item whose
|
|
52
|
+
* container has closed and whose successor has not parked yet answers
|
|
53
|
+
* `no_open_container` with the item row, so the station can say "scan
|
|
54
|
+
* again" instead of showing the item with no hint.
|
|
55
|
+
* - Container-locate (no `containerFacet`): the scan locates the container
|
|
56
|
+
* by the scheme facet and adds `params.itemKey` (template).
|
|
57
|
+
*
|
|
58
|
+
* Templates may read `{claim.<facet>}` (the actor's live claim) and, in item
|
|
59
|
+
* mode, `{item.<facet>}` (the located row); an unresolvable token falls
|
|
60
|
+
* through. The write is the SDK's guarded statement; the locate only picks
|
|
61
|
+
* ids. A container already holding the item answers conflict, never a
|
|
62
|
+
* second add.
|
|
63
|
+
*/
|
|
64
|
+
async function accumulateStep(step, ctx) {
|
|
65
|
+
const options = step.params?.accumulate;
|
|
66
|
+
if (options?.from === 'subject')
|
|
67
|
+
return (0, verbs_subject_1.accumulateFromSubject)(step, ctx);
|
|
68
|
+
if (options?.into === 'subject')
|
|
69
|
+
return (0, verbs_subject_1.accumulateIntoSubject)(step, ctx);
|
|
70
|
+
let item;
|
|
71
|
+
if (options?.containerFacet) {
|
|
72
|
+
const located = await (0, locate_1.locateForStep)(step, ctx, 1);
|
|
73
|
+
item = located?.escalations[0];
|
|
74
|
+
if (!item)
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const rendered = await (0, context_1.templated)(step, ctx, (tpl) => ({
|
|
78
|
+
payload: step.params?.resolverPayload
|
|
79
|
+
? scanCodeService.interpolateScanTemplate(step.params.resolverPayload, tpl)
|
|
80
|
+
: undefined,
|
|
81
|
+
metadata: { ...(0, context_1.interpolatedMetadata)(step, ctx, tpl), ...(0, context_1.provenance)(ctx) },
|
|
82
|
+
itemKey: options?.containerFacet
|
|
83
|
+
? ctx.parsed.target
|
|
84
|
+
: scanCodeService.interpolateScanTemplate(step.params.itemKey, tpl),
|
|
85
|
+
}), item);
|
|
86
|
+
if (rendered === null)
|
|
87
|
+
return null;
|
|
88
|
+
let request;
|
|
89
|
+
let container;
|
|
90
|
+
if (options?.containerFacet && item) {
|
|
91
|
+
const containerValue = item.metadata?.[options.containerFacet];
|
|
92
|
+
if (containerValue === undefined || containerValue === null || containerValue === '')
|
|
93
|
+
return null;
|
|
94
|
+
container = { facet: options.containerFacet, value: String(containerValue) };
|
|
95
|
+
request = {
|
|
96
|
+
key: container.facet,
|
|
97
|
+
value: container.value,
|
|
98
|
+
itemKey: rendered.itemKey,
|
|
99
|
+
payload: rendered.payload,
|
|
100
|
+
metadata: rendered.metadata,
|
|
101
|
+
restrictRoles: options.container?.roles ?? options.containerRoles,
|
|
102
|
+
container: options.container
|
|
103
|
+
? { types: options.container.types, subtypes: options.container.subtypes, facets: options.container.facets }
|
|
104
|
+
: undefined,
|
|
105
|
+
...(options.reciprocal === false ? {} : { reciprocal: { id: item.id } }),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
request = {
|
|
110
|
+
key: ctx.scheme.target_facet,
|
|
111
|
+
value: ctx.parsed.target,
|
|
112
|
+
itemKey: rendered.itemKey,
|
|
113
|
+
payload: rendered.payload,
|
|
114
|
+
metadata: rendered.metadata,
|
|
115
|
+
restrictRoles: step.query?.roles,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const notPrimed = await (0, grant_1.spendGrant)(ctx);
|
|
119
|
+
if (notPrimed)
|
|
120
|
+
return notPrimed;
|
|
121
|
+
const result = await (0, accumulate_1.accumulateItemByMetadata)(request, ctx.auth);
|
|
122
|
+
if (result.status === 404) {
|
|
123
|
+
if (!container || !item)
|
|
124
|
+
return null;
|
|
125
|
+
return {
|
|
126
|
+
status: 200,
|
|
127
|
+
data: {
|
|
128
|
+
outcome: types_1.SCAN_OUTCOMES.NO_OPEN_CONTAINER,
|
|
129
|
+
verb: step.verb,
|
|
130
|
+
escalation: item,
|
|
131
|
+
container,
|
|
132
|
+
fallback: ctx.rule.fallback,
|
|
133
|
+
error: `No open container carries ${container.facet} = ${container.value}`,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (result.status === 403)
|
|
138
|
+
return (0, context_1.forbidden)(result.error);
|
|
139
|
+
if (result.status === 409)
|
|
140
|
+
return (0, context_1.conflict)(result.error);
|
|
141
|
+
if (result.status === 400 || result.status === 422)
|
|
142
|
+
return (0, context_1.refused)(result.error ?? 'the item was not accepted');
|
|
143
|
+
if (result.status !== 200)
|
|
144
|
+
return result;
|
|
145
|
+
const escalation = result.data.escalationId ? { id: result.data.escalationId, ...result.data } : undefined;
|
|
146
|
+
return (0, context_1.executed)(escalation, step);
|
|
147
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ScanExecuteResponse, type ScanStep } from '../../types';
|
|
2
|
+
import type { LTApiResult } from '../../types/sdk';
|
|
3
|
+
import { type StepContext } from './context';
|
|
4
|
+
type ScanResult = LTApiResult<ScanExecuteResponse>;
|
|
5
|
+
export declare function fillStep(step: ScanStep, ctx: StepContext): Promise<ScanResult | null>;
|
|
6
|
+
export {};
|