@hotmeshio/long-tail 0.22.1 → 0.22.3
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/lookups.d.ts +9 -2
- package/build/api/escalations/lookups.js +15 -3
- package/build/api/escalations/metadata.d.ts +2 -0
- package/build/api/escalations/metadata.js +9 -0
- 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/locate.js +4 -0
- package/build/api/scan-codes/present.d.ts +1 -1
- package/build/api/scan-codes/present.js +43 -0
- 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 +151 -0
- package/build/api/scan-codes/verb-fill.d.ts +6 -0
- package/build/api/scan-codes/verb-fill.js +155 -0
- package/build/api/scan-codes/verb-into-subject.d.ts +12 -0
- package/build/api/scan-codes/verb-into-subject.js +157 -0
- package/build/api/scan-codes/verbs-subject.d.ts +33 -0
- package/build/api/scan-codes/verbs-subject.js +247 -0
- package/build/api/scan-codes/verbs.d.ts +11 -29
- package/build/api/scan-codes/verbs.js +51 -131
- package/build/index.d.ts +1 -0
- package/build/index.js +9 -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/sdk/index.d.ts +1 -0
- package/build/services/escalation/claim-asserted.d.ts +10 -0
- package/build/services/escalation/claim-asserted.js +64 -0
- package/build/services/escalation/facets.d.ts +3 -1
- package/build/services/escalation/facets.js +7 -3
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +3 -1
- 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/knowledge/lookup-cache.d.ts +16 -4
- package/build/services/knowledge/lookup-cache.js +53 -20
- package/build/services/knowledge/lookup-refs.d.ts +3 -2
- package/build/services/knowledge/lookup-refs.js +6 -4
- package/build/services/knowledge/sql.d.ts +2 -0
- package/build/services/knowledge/sql.js +9 -1
- package/build/services/mcp/server-tools.js +1 -1
- package/build/services/orchestrator/condition.d.ts +13 -10
- package/build/services/orchestrator/condition.js +8 -6
- 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 +8 -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-facts.d.ts +5 -0
- package/build/services/scan-code/validate-facts.js +24 -0
- package/build/services/scan-code/validate-query.d.ts +8 -0
- package/build/services/scan-code/validate-query.js +36 -0
- package/build/services/scan-code/validate-subject.d.ts +7 -0
- package/build/services/scan-code/validate-subject.js +185 -0
- package/build/services/scan-code/validate.d.ts +7 -0
- package/build/services/scan-code/validate.js +103 -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 +11 -0
- package/build/shared/scan-code/gtin.js +38 -0
- package/build/shared/scan-code/index.d.ts +2 -0
- package/build/shared/scan-code/index.js +11 -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 +939 -28
- package/build/system/mcp-servers/admin/schemas.js +72 -6
- package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
- package/build/system/seed/tool-manifests-admin.d.ts +202 -1
- package/build/system/seed/tool-manifests-admin.js +2 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +16 -8
- package/build/types/escalation.js +18 -7
- package/build/types/index.d.ts +4 -4
- package/build/types/index.js +10 -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 +145 -0
- package/build/types/scan-code/response.js +2 -0
- package/build/types/scan-code/rule.d.ts +229 -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-hI5-kKpL.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BbWve-Ax.js.map → AdminDashboard-hI5-kKpL.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js → AgentConfigPage-DetU4HZe.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js.map → AgentConfigPage-DetU4HZe.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js → AgentDetailPage-DrGXo8KQ.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js.map → AgentDetailPage-DrGXo8KQ.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js → AgentsPage-D4md5BzM.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js.map → AgentsPage-D4md5BzM.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js → AvailableEscalationsPage-B2bS2ZJy.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js.map → AvailableEscalationsPage-B2bS2ZJy.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-CGB16rYU.js → BotPicker-BXtey255.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CGB16rYU.js.map → BotPicker-BXtey255.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js → BulkAssignModal-CSL_PeZv.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js.map → BulkAssignModal-CSL_PeZv.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-5scufTHW.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-BxadotXn.js.map → CapabilitiesPage-5scufTHW.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js → CollapsibleSection-DjjDGxP_.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js.map → CollapsibleSection-DjjDGxP_.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js → ConfirmDeleteModal-DJSmsHQM.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js.map → ConfirmDeleteModal-DJSmsHQM.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-C5ZRYPfF.js +2 -0
- package/dashboard/dist/assets/{CountdownTimer-CI_JOAvk.js.map → CountdownTimer-C5ZRYPfF.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js → CredentialsPage-CV6e60yC.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js.map → CredentialsPage-CV6e60yC.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js → CronLabel-CnqhqW0B.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js.map → CronLabel-CnqhqW0B.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js → ElapsedCell-C1IOn-tj.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js.map → ElapsedCell-C1IOn-tj.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js → EntityTimelinePanel-Dz6Liig4.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js.map → EntityTimelinePanel-Dz6Liig4.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js → EscalationListSchemaPage-bgdmLmrh.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js.map → EscalationListSchemaPage-bgdmLmrh.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js → EscalationListView-CrlD3ZGt.js} +2 -2
- package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js.map → EscalationListView-CrlD3ZGt.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js → EscalationSchemaPage-dxXO_T3t.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js.map → EscalationSchemaPage-dxXO_T3t.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js → EscalationTimeline-C3WQZQuM.js} +2 -2
- package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js.map → EscalationTimeline-C3WQZQuM.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js → EscalationTitleSelect-CTtcETUO.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js.map → EscalationTitleSelect-CTtcETUO.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js → EscalationsOverview-DAjZ7JY2.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js.map → EscalationsOverview-DAjZ7JY2.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DSHqKyX2.js → EventTable-B72DQP_v.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DSHqKyX2.js.map → EventTable-B72DQP_v.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js → FilterBar-CCTaA_LH.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js.map → FilterBar-CCTaA_LH.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-CAsCgFo3.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-ChqqGkro.js.map → GraphInvokePage-CAsCgFo3.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-ByKesG8w.js → HomePage-DseE_iSr.js} +2 -2
- package/dashboard/dist/assets/{HomePage-ByKesG8w.js.map → HomePage-DseE_iSr.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js → ListToolbar-1zdqnjW6.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js.map → ListToolbar-1zdqnjW6.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CVe13tEv.js → McpOverview-DS_JXDW5.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CVe13tEv.js.map → McpOverview-DS_JXDW5.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js → McpQueryDetailPage-BeMUGcv3.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js.map → McpQueryDetailPage-BeMUGcv3.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js → McpQueryPage-CeiLO_LR.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js.map → McpQueryPage-CeiLO_LR.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js → McpRunDetailPage-DYp1uZK2.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js.map → McpRunDetailPage-DYp1uZK2.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js → McpRunsPage-VeaDzcL4.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js.map → McpRunsPage-VeaDzcL4.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js → OperationsPage-DK2mgaXf.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js.map → OperationsPage-DK2mgaXf.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js → OperatorDashboard-BNjLF0f7.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js.map → OperatorDashboard-BNjLF0f7.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js → PersonaDetailPage-IQ2fZLa6.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js.map → PersonaDetailPage-IQ2fZLa6.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js → PersonasPage-DpGFEcU-.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js.map → PersonasPage-DpGFEcU-.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js → PortalPage-D07xyvG_.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js.map → PortalPage-D07xyvG_.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js → ProcessDetailPage-t8EEYSMk.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js.map → ProcessDetailPage-t8EEYSMk.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js → ProcessesListPage-BDUXLFdb.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js.map → ProcessesListPage-BDUXLFdb.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-BwWOYv_Z.js +8 -0
- package/dashboard/dist/assets/ResolverForm-BwWOYv_Z.js.map +1 -0
- package/dashboard/dist/assets/RoleDetailPage-zMF3x2xi.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-zMF3x2xi.js.map +1 -0
- package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js → RolesPage-CEBp_PpL.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js.map → RolesPage-CEBp_PpL.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js → RunAsSelector-CC_EHN3z.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js.map → RunAsSelector-CC_EHN3z.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-DD4uU-jY.js +2 -0
- package/dashboard/dist/assets/ScanCodesPage-DD4uU-jY.js.map +1 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js → StickyPagination-cNqSDm5f.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js.map → StickyPagination-cNqSDm5f.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js → StreamMessageDetail-C4oZqQdB.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js.map → StreamMessageDetail-C4oZqQdB.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js → SwimlaneTimeline-BjBiV7GT.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js.map → SwimlaneTimeline-BjBiV7GT.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js → TaskDetailPage-pO_AnVS1.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js.map → TaskDetailPage-pO_AnVS1.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js → TasksListPage-DKDHlWP7.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js.map → TasksListPage-DKDHlWP7.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js → TimeAgo-D2qchUuJ.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js.map → TimeAgo-D2qchUuJ.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js → TimestampCell-DeswZGGo.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js.map → TimestampCell-DeswZGGo.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js → ToolTestPanel-DJh7PIUa.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js.map → ToolTestPanel-DJh7PIUa.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js → TopicDetailPage-CsgDJ4Z4.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js.map → TopicDetailPage-CsgDJ4Z4.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js → TopicsPage-tBRZDVDN.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js.map → TopicsPage-tBRZDVDN.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CXsdPiMZ.js → UserName-B-5JcDck.js} +2 -2
- package/dashboard/dist/assets/{UserName-CXsdPiMZ.js.map → UserName-B-5JcDck.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js → WorkflowExecutionPage-BPHVnhp6.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js.map → WorkflowExecutionPage-BPHVnhp6.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js → WorkflowsDashboard-CxLlfZmY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js.map → WorkflowsDashboard-CxLlfZmY.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js → WorkflowsOverview-C4az5rwp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js.map → WorkflowsOverview-C4az5rwp.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js → YamlWorkflowDetailPage-BmhlAUFQ.js} +8 -8
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js.map → YamlWorkflowDetailPage-BmhlAUFQ.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js → YamlWorkflowsPage-CSbG5o2V.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js.map → YamlWorkflowsPage-CSbG5o2V.js.map} +1 -1
- package/dashboard/dist/assets/{agents-v_HH3Rji.js → agents-BohEn7vw.js} +2 -2
- package/dashboard/dist/assets/{agents-v_HH3Rji.js.map → agents-BohEn7vw.js.map} +1 -1
- package/dashboard/dist/assets/{bots-bwvWYrXz.js → bots-BG2EO-Wi.js} +2 -2
- package/dashboard/dist/assets/{bots-bwvWYrXz.js.map → bots-BG2EO-Wi.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js → capabilities-CeFrBmYX.js} +2 -2
- package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js.map → capabilities-CeFrBmYX.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js → controlplane-Dhvt8l8F.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js.map → controlplane-Dhvt8l8F.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js → escalation-columns-BWMNxImp.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js.map → escalation-columns-BWMNxImp.js.map} +1 -1
- package/dashboard/dist/assets/{index-CzjUgFt_.js → index-Bd_dgyfJ.js} +2 -2
- package/dashboard/dist/assets/{index-CzjUgFt_.js.map → index-Bd_dgyfJ.js.map} +1 -1
- package/dashboard/dist/assets/{index-IJmtbuLh.js → index-C8VlM2Oe.js} +2 -2
- package/dashboard/dist/assets/{index-IJmtbuLh.js.map → index-C8VlM2Oe.js.map} +1 -1
- package/dashboard/dist/assets/{index-CcuvGdvf.js → index-CiqSVDga.js} +2 -2
- package/dashboard/dist/assets/{index-CcuvGdvf.js.map → index-CiqSVDga.js.map} +1 -1
- package/dashboard/dist/assets/{index-C3WutFpT.js → index-Cl_YXEdp.js} +2 -2
- package/dashboard/dist/assets/{index-C3WutFpT.js.map → index-Cl_YXEdp.js.map} +1 -1
- package/dashboard/dist/assets/index-CtZWpy22.js +2 -0
- package/dashboard/dist/assets/index-CtZWpy22.js.map +1 -0
- package/dashboard/dist/assets/{index-CjenRVX_.js → index-D90D9y0J.js} +2 -2
- package/dashboard/dist/assets/{index-CjenRVX_.js.map → index-D90D9y0J.js.map} +1 -1
- package/dashboard/dist/assets/{index-BLB77tc8.js → index-DABkM7s-.js} +2 -2
- package/dashboard/dist/assets/{index-BLB77tc8.js.map → index-DABkM7s-.js.map} +1 -1
- package/dashboard/dist/assets/index-Dbwu51xm.js +3 -0
- package/dashboard/dist/assets/index-Dbwu51xm.js.map +1 -0
- package/dashboard/dist/assets/{index-2tzsxFat.js → index-Dc3Om6G3.js} +2 -2
- package/dashboard/dist/assets/{index-2tzsxFat.js.map → index-Dc3Om6G3.js.map} +1 -1
- package/dashboard/dist/assets/{index-D2VKBMng.js → index-Dc_zWK23.js} +2 -2
- package/dashboard/dist/assets/{index-D2VKBMng.js.map → index-Dc_zWK23.js.map} +1 -1
- package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
- package/dashboard/dist/assets/{index-C_ISDOWJ.js → index-Y-bdW8vo.js} +2 -2
- package/dashboard/dist/assets/{index-C_ISDOWJ.js.map → index-Y-bdW8vo.js.map} +1 -1
- package/dashboard/dist/assets/{index-C4Lce2ET.js → index-dYKgd06u.js} +3 -3
- package/dashboard/dist/assets/{index-C4Lce2ET.js.map → index-dYKgd06u.js.map} +1 -1
- package/dashboard/dist/assets/index-fUsx_gYx.js +67 -0
- package/dashboard/dist/assets/index-fUsx_gYx.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-D1YP2NzS.js → knowledge-CCcTidNV.js} +2 -2
- package/dashboard/dist/assets/{knowledge-D1YP2NzS.js.map → knowledge-CCcTidNV.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Bb5psC61.js → mcp-CLA1z7Pg.js} +2 -2
- package/dashboard/dist/assets/{mcp-Bb5psC61.js.map → mcp-CLA1z7Pg.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js → mcp-query-CWG0WMAs.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js.map → mcp-query-CWG0WMAs.js.map} +1 -1
- package/dashboard/dist/assets/metadata-display-B7X5hGxG.js +2 -0
- package/dashboard/dist/assets/metadata-display-B7X5hGxG.js.map +1 -0
- package/dashboard/dist/assets/{personas-CDndbkp4.js → personas-8jURIzx6.js} +2 -2
- package/dashboard/dist/assets/{personas-CDndbkp4.js.map → personas-8jURIzx6.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js → pipelines-hVVRAXqG.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js.map → pipelines-hVVRAXqG.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BlpDsWCy.js → tasks-BE1O57Bf.js} +2 -2
- package/dashboard/dist/assets/{tasks-BlpDsWCy.js.map → tasks-BE1O57Bf.js.map} +1 -1
- package/dashboard/dist/assets/{topics-C0YaR9fu.js → topics-Bg96Wp1r.js} +2 -2
- package/dashboard/dist/assets/{topics-C0YaR9fu.js.map → topics-Bg96Wp1r.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js → useDebouncedValue-DmEveyEy.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js.map → useDebouncedValue-DmEveyEy.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js → useNamespace-DHgkzIuL.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js.map → useNamespace-DHgkzIuL.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js → useYamlActivityEvents-RU0PvU8S.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js.map → useYamlActivityEvents-RU0PvU8S.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js → yaml-workflows-DQWE9ijc.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js.map → yaml-workflows-DQWE9ijc.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/dashboard.md +1 -1
- package/docs/hitl/lookups.md +27 -18
- package/docs/hitl/x-lt-scan.md +51 -0
- package/docs/hitl/x-lt-validation.md +1 -1
- package/docs/hitl/x-lt-widget.md +1 -1
- package/docs/hitl-guide.md +3 -1
- package/docs/scan-codes.md +303 -33
- 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-D6pBLZFu.js +0 -2
- package/dashboard/dist/assets/index-D6pBLZFu.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
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js +0 -2
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +0 -1
|
@@ -37,10 +37,15 @@ exports.executeScanCode = executeScanCode;
|
|
|
37
37
|
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
38
38
|
const identity_1 = require("./identity");
|
|
39
39
|
const context_1 = require("./context");
|
|
40
|
+
const grant_1 = require("./grant");
|
|
41
|
+
const hold_1 = require("./hold");
|
|
40
42
|
const locate_1 = require("./locate");
|
|
41
43
|
const present_1 = require("./present");
|
|
44
|
+
const subject_1 = require("./subject");
|
|
45
|
+
const verb_fill_1 = require("./verb-fill");
|
|
42
46
|
const verbs_1 = require("./verbs");
|
|
43
47
|
const types_1 = require("../../types");
|
|
48
|
+
const SUBJECT_STALE_MESSAGE = 'That one moved on. Scan it again.';
|
|
44
49
|
/**
|
|
45
50
|
* Execute a raw scan code: parse → load the rule → walk its steps in order.
|
|
46
51
|
* The first step whose condition matches performs its verb and answers; a
|
|
@@ -77,45 +82,57 @@ async function executeScanCode(input, auth) {
|
|
|
77
82
|
}
|
|
78
83
|
// 2a. Identity schemes are the badge layer — they mint, never walk steps.
|
|
79
84
|
if (scheme.kind === types_1.SCAN_SCHEME_KINDS.IDENTITY) {
|
|
80
|
-
return (0, identity_1.executeIdentityScan)(parsed, scheme, rule, input.previousActingToken
|
|
85
|
+
return (0, identity_1.executeIdentityScan)(parsed, scheme, rule, input.previousActingToken, {
|
|
86
|
+
userId: auth.userId,
|
|
87
|
+
stationRole: typeof input.stationRole === 'string' ? input.stationRole : undefined,
|
|
88
|
+
});
|
|
81
89
|
}
|
|
82
|
-
// 2b. A supplied acting grant is
|
|
83
|
-
// user's read scope
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
// 2b. A supplied acting grant is read up front (not spent): the acting
|
|
91
|
+
// user's read scope governs the locate as much as the mutation. A dead
|
|
92
|
+
// grant terminates loudly; silently degrading to the station identity
|
|
93
|
+
// would misattribute whatever follows.
|
|
94
|
+
const ctx = {
|
|
95
|
+
scheme, rule, parsed, rawCode: input.code.trim(), scannedAt: new Date().toISOString(),
|
|
96
|
+
auth, stationAuth: auth, acting: false,
|
|
97
|
+
};
|
|
88
98
|
if (input.actingToken) {
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
91
|
-
return {
|
|
92
|
-
status: 200,
|
|
93
|
-
data: {
|
|
94
|
-
outcome: types_1.SCAN_OUTCOMES.NOT_PRIMED,
|
|
95
|
-
parsed,
|
|
96
|
-
notPrimed: rule.notPrimed,
|
|
97
|
-
error: resolved.error,
|
|
98
|
-
},
|
|
99
|
-
};
|
|
99
|
+
const peeked = await (0, grant_1.peekGrant)(input.actingToken);
|
|
100
|
+
if (!peeked.ok) {
|
|
101
|
+
return { status: 200, data: { ...(0, context_1.notPrimed)(ctx, peeked.error).data, parsed } };
|
|
100
102
|
}
|
|
101
|
-
|
|
102
|
-
acting = true;
|
|
103
|
+
ctx.auth = peeked.auth;
|
|
104
|
+
ctx.acting = true;
|
|
105
|
+
ctx.grant = peeked.grant;
|
|
103
106
|
}
|
|
107
|
+
// 2c. The held subject, re-derived from the station's pointer
|
|
108
|
+
const held = await (0, subject_1.resolveSubject)(input.subject, schemes, auth);
|
|
109
|
+
if (held?.ok)
|
|
110
|
+
ctx.subject = held.subject;
|
|
111
|
+
else if (held)
|
|
112
|
+
ctx.subjectStale = true;
|
|
104
113
|
// 3. Walk the steps — first condition match wins
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const result = await executeStep(rule.steps[i], i, ctx);
|
|
111
|
-
if (result)
|
|
112
|
-
return decorate(result, ctx, i);
|
|
114
|
+
let result = null;
|
|
115
|
+
for (let i = 0; i < rule.steps.length && !result; i++) {
|
|
116
|
+
const stepResult = await executeStep(rule.steps[i], ctx);
|
|
117
|
+
if (stepResult)
|
|
118
|
+
result = decorate((0, context_1.withDone)(stepResult, rule.steps[i], (0, context_1.templateContext)(ctx)), ctx, i);
|
|
113
119
|
}
|
|
114
|
-
// 4. Nothing matched
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
// 4. Nothing matched: a stale subject, or the fallback screen
|
|
121
|
+
if (!result) {
|
|
122
|
+
result = ctx.subjectStale
|
|
123
|
+
? { status: 200, data: decorateData({ outcome: types_1.SCAN_OUTCOMES.SUBJECT_STALE, clearSubject: true, error: SUBJECT_STALE_MESSAGE }, ctx) }
|
|
124
|
+
: { status: 200, data: decorateData({ outcome: types_1.SCAN_OUTCOMES.NO_MATCH_FALLBACK, fallback: rule.fallback }, ctx) };
|
|
125
|
+
}
|
|
126
|
+
// 5. Settle the badge: refund a spend whose act did not land
|
|
127
|
+
const acting = await (0, grant_1.settleGrant)(ctx, result);
|
|
128
|
+
if (result.data && typeof result.data === 'object' && 'outcome' in result.data) {
|
|
129
|
+
result.data = {
|
|
130
|
+
...result.data,
|
|
131
|
+
...(acting ? { acting } : {}),
|
|
132
|
+
...(ctx.subjectStale ? { clearSubject: true } : {}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
119
136
|
}
|
|
120
137
|
catch (err) {
|
|
121
138
|
return { status: 500, error: err.message };
|
|
@@ -139,17 +156,34 @@ function decorateData(data, ctx) {
|
|
|
139
156
|
},
|
|
140
157
|
};
|
|
141
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* A subject step runs only while a subject from one of its schemes is held,
|
|
161
|
+
* and, when it declares facets, only while the held row carries them.
|
|
162
|
+
*/
|
|
163
|
+
function subjectGateOpen(step, ctx) {
|
|
164
|
+
if (!step.subject)
|
|
165
|
+
return true;
|
|
166
|
+
if (!ctx.subject || !step.subject.schemes.includes(ctx.subject.scheme.version))
|
|
167
|
+
return false;
|
|
168
|
+
const meta = (ctx.subject.row.metadata ?? {});
|
|
169
|
+
return Object.entries(step.subject.facets ?? {}).every(([key, value]) => meta[key] === value);
|
|
170
|
+
}
|
|
142
171
|
/**
|
|
143
172
|
* Execute one step. Returns null when the step's condition matched nothing
|
|
144
173
|
* (fall through) and an LTApiResult for every terminal outcome.
|
|
145
174
|
*/
|
|
146
|
-
async function executeStep(step,
|
|
175
|
+
async function executeStep(step, ctx) {
|
|
176
|
+
if (!subjectGateOpen(step, ctx))
|
|
177
|
+
return null;
|
|
147
178
|
// The identity pre-condition: the effective actor must be a real acting
|
|
148
179
|
// identity — a badge grant, or an authenticated user whose own write scope
|
|
149
180
|
// covers the step. A write-incapable shared account can never self-satisfy,
|
|
150
181
|
// so the outcome is the rule's "scan your badge" screen, never a silent or
|
|
151
182
|
// misattributed action.
|
|
152
|
-
|
|
183
|
+
// A subject step checks the pairing first and asks for the badge only when
|
|
184
|
+
// the pairing is right (see identityGate), so a wrong container is named
|
|
185
|
+
// at once.
|
|
186
|
+
if (step.requireActingIdentity && !step.subject && !(await (0, identity_1.actingIdentitySatisfied)(step, ctx))) {
|
|
153
187
|
return (0, context_1.notPrimed)(ctx);
|
|
154
188
|
}
|
|
155
189
|
// Confirm steps and read verbs only locate — mutation happens after the
|
|
@@ -160,6 +194,8 @@ async function executeStep(step, index, ctx) {
|
|
|
160
194
|
switch (step.verb) {
|
|
161
195
|
case types_1.SCAN_VERBS.PRESENT:
|
|
162
196
|
return (0, present_1.presentStep)(step, ctx);
|
|
197
|
+
case types_1.SCAN_VERBS.HOLD:
|
|
198
|
+
return (0, hold_1.holdStep)(step, ctx);
|
|
163
199
|
case types_1.SCAN_VERBS.CLAIM:
|
|
164
200
|
case types_1.SCAN_VERBS.CLAIM_SHOW_DETAIL:
|
|
165
201
|
return (0, verbs_1.claimStep)(step, ctx);
|
|
@@ -173,6 +209,8 @@ async function executeStep(step, index, ctx) {
|
|
|
173
209
|
return (0, verbs_1.cancelStep)(step, ctx);
|
|
174
210
|
case types_1.SCAN_VERBS.ACCUMULATE:
|
|
175
211
|
return (0, verbs_1.accumulateStep)(step, ctx);
|
|
212
|
+
case types_1.SCAN_VERBS.FILL:
|
|
213
|
+
return (0, verb_fill_1.fillStep)(step, ctx);
|
|
176
214
|
default:
|
|
177
215
|
throw new Error(`unknown scan verb "${step.verb}"`);
|
|
178
216
|
}
|
|
@@ -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
|
}
|
|
@@ -61,6 +61,8 @@ async function locateForStep(step, ctx, limit) {
|
|
|
61
61
|
return escalationService.listEscalations({
|
|
62
62
|
metadata: facets,
|
|
63
63
|
status,
|
|
64
|
+
type: step.query?.types?.[0],
|
|
65
|
+
subtype: step.query?.subtypes?.[0],
|
|
64
66
|
assigned_to: ctx.auth.userId,
|
|
65
67
|
visibleRoles: roles ?? undefined,
|
|
66
68
|
limit,
|
|
@@ -71,6 +73,8 @@ async function locateForStep(step, ctx, limit) {
|
|
|
71
73
|
return null;
|
|
72
74
|
return escalationService.searchByFacets({
|
|
73
75
|
roles: roles ?? undefined,
|
|
76
|
+
types: step.query?.types,
|
|
77
|
+
subtypes: step.query?.subtypes,
|
|
74
78
|
facets,
|
|
75
79
|
status,
|
|
76
80
|
available: availability === types_1.SCAN_AVAILABILITY.AVAILABLE
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ScanExecuteResponse, type ScanStep } from '../../types';
|
|
2
2
|
import type { LTApiResult } from '../../types/sdk';
|
|
3
|
-
import type
|
|
3
|
+
import { type StepContext } from './context';
|
|
4
4
|
/**
|
|
5
5
|
* Locate the target and present the step's choices. Choices whose identity
|
|
6
6
|
* requirement is unsatisfied come back withheld — the screen renders the
|
|
@@ -1,10 +1,52 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.presentStep = presentStep;
|
|
37
|
+
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
4
38
|
const types_1 = require("../../types");
|
|
5
39
|
const identity_1 = require("./identity");
|
|
6
40
|
const locate_1 = require("./locate");
|
|
7
41
|
const verbs_1 = require("./verbs");
|
|
42
|
+
const context_1 = require("./context");
|
|
43
|
+
/** The step's facts rendered against the presented row; unreadable tokens render empty. */
|
|
44
|
+
function renderFacts(step, ctx, row) {
|
|
45
|
+
if (!step.facts)
|
|
46
|
+
return undefined;
|
|
47
|
+
const tpl = { ...(0, context_1.templateContext)(ctx), item: row.metadata ?? {} };
|
|
48
|
+
return step.facts.map((fact) => ({ label: fact.label, value: scanCodeService.renderScanCopy(fact.value, tpl) }));
|
|
49
|
+
}
|
|
8
50
|
// ── The info-choice outcome — locate → present reality + labeled choices ───
|
|
9
51
|
//
|
|
10
52
|
// Some objects carry one code for their whole life: the next action cannot be
|
|
@@ -52,6 +94,7 @@ async function presentStep(step, ctx) {
|
|
|
52
94
|
verb: step.verb,
|
|
53
95
|
escalation,
|
|
54
96
|
choices,
|
|
97
|
+
...(step.facts ? { facts: renderFacts(step, ctx, escalation) } : {}),
|
|
55
98
|
notPrimed: ctx.rule.notPrimed,
|
|
56
99
|
...(autoSelect ? { autoSelect: true } : {}),
|
|
57
100
|
},
|
|
@@ -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
|
+
}
|