@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.
Files changed (291) hide show
  1. package/build/api/escalations/accumulate.js +38 -19
  2. package/build/api/escalations/resolve-batch.js +18 -11
  3. package/build/api/roles.js +4 -0
  4. package/build/api/scan-codes/badge-policy.d.ts +10 -0
  5. package/build/api/scan-codes/badge-policy.js +72 -0
  6. package/build/api/scan-codes/choice.js +16 -10
  7. package/build/api/scan-codes/context.d.ts +45 -1
  8. package/build/api/scan-codes/context.js +51 -3
  9. package/build/api/scan-codes/execute.js +73 -35
  10. package/build/api/scan-codes/grant.d.ts +27 -0
  11. package/build/api/scan-codes/grant.js +67 -0
  12. package/build/api/scan-codes/hold.d.ts +10 -0
  13. package/build/api/scan-codes/hold.js +98 -0
  14. package/build/api/scan-codes/identity.d.ts +5 -2
  15. package/build/api/scan-codes/identity.js +26 -8
  16. package/build/api/scan-codes/subject.d.ts +15 -0
  17. package/build/api/scan-codes/subject.js +68 -0
  18. package/build/api/scan-codes/verb-accumulate.d.ts +24 -0
  19. package/build/api/scan-codes/verb-accumulate.js +147 -0
  20. package/build/api/scan-codes/verb-fill.d.ts +6 -0
  21. package/build/api/scan-codes/verb-fill.js +152 -0
  22. package/build/api/scan-codes/verbs-subject.d.ts +14 -0
  23. package/build/api/scan-codes/verbs-subject.js +270 -0
  24. package/build/api/scan-codes/verbs.d.ts +1 -21
  25. package/build/api/scan-codes/verbs.js +26 -115
  26. package/build/index.d.ts +1 -0
  27. package/build/index.js +8 -2
  28. package/build/lib/db/schemas/037_scan_gtin_and_subject_grants.sql +27 -0
  29. package/build/routes/escalations/acting.d.ts +5 -0
  30. package/build/routes/escalations/acting.js +8 -1
  31. package/build/routes/scan-codes.js +3 -0
  32. package/build/services/iam/acting-identity.d.ts +29 -4
  33. package/build/services/iam/acting-identity.js +60 -17
  34. package/build/services/iam/ephemeral.d.ts +21 -0
  35. package/build/services/iam/ephemeral.js +32 -1
  36. package/build/services/iam/sql.d.ts +10 -0
  37. package/build/services/iam/sql.js +32 -3
  38. package/build/services/role/badge-grant.d.ts +5 -0
  39. package/build/services/role/badge-grant.js +36 -0
  40. package/build/services/role/seed.js +5 -0
  41. package/build/services/role/types.d.ts +14 -0
  42. package/build/services/role/types.js +5 -0
  43. package/build/services/scan-code/index.d.ts +3 -2
  44. package/build/services/scan-code/index.js +7 -1
  45. package/build/services/scan-code/parse.d.ts +23 -20
  46. package/build/services/scan-code/parse.js +45 -90
  47. package/build/services/scan-code/read.js +1 -0
  48. package/build/services/scan-code/sql.d.ts +3 -3
  49. package/build/services/scan-code/sql.js +11 -8
  50. package/build/services/scan-code/validate-subject.d.ts +7 -0
  51. package/build/services/scan-code/validate-subject.js +158 -0
  52. package/build/services/scan-code/validate.d.ts +7 -0
  53. package/build/services/scan-code/validate.js +94 -18
  54. package/build/services/scan-code/write.d.ts +1 -0
  55. package/build/services/scan-code/write.js +9 -3
  56. package/build/shared/form-validation/field-validator.js +4 -0
  57. package/build/shared/form-validation/index.d.ts +1 -0
  58. package/build/shared/form-validation/index.js +1 -0
  59. package/build/shared/form-validation/x-lt-scan.d.ts +52 -0
  60. package/build/shared/form-validation/x-lt-scan.js +166 -0
  61. package/build/shared/scan-code/gtin.d.ts +5 -0
  62. package/build/shared/scan-code/gtin.js +25 -0
  63. package/build/shared/scan-code/index.d.ts +2 -0
  64. package/build/shared/scan-code/index.js +10 -0
  65. package/build/shared/scan-code/parse.d.ts +46 -0
  66. package/build/shared/scan-code/parse.js +133 -0
  67. package/build/system/mcp-servers/admin/scan-codes.js +10 -4
  68. package/build/system/mcp-servers/admin/schemas.d.ts +754 -23
  69. package/build/system/mcp-servers/admin/schemas.js +57 -4
  70. package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
  71. package/build/tsconfig.tsbuildinfo +1 -1
  72. package/build/types/escalation.d.ts +2 -0
  73. package/build/types/escalation.js +3 -1
  74. package/build/types/index.d.ts +2 -2
  75. package/build/types/index.js +8 -1
  76. package/build/types/scan-code/constants.d.ts +182 -0
  77. package/build/types/{scan-code.js → scan-code/constants.js} +72 -11
  78. package/build/types/scan-code/index.d.ts +3 -0
  79. package/build/types/scan-code/index.js +17 -0
  80. package/build/types/scan-code/response.d.ts +140 -0
  81. package/build/types/scan-code/response.js +2 -0
  82. package/build/types/scan-code/rule.d.ts +199 -0
  83. package/build/types/scan-code/rule.js +2 -0
  84. package/build/types/startup.d.ts +3 -1
  85. package/dashboard/dist/assets/{AdminDashboard-BbWve-Ax.js → AdminDashboard-DBW12qQt.js} +2 -2
  86. package/dashboard/dist/assets/{AdminDashboard-BbWve-Ax.js.map → AdminDashboard-DBW12qQt.js.map} +1 -1
  87. package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js → AgentConfigPage-CmHv8U9M.js} +2 -2
  88. package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js.map → AgentConfigPage-CmHv8U9M.js.map} +1 -1
  89. package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js → AgentDetailPage-D1scIbz-.js} +3 -3
  90. package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js.map → AgentDetailPage-D1scIbz-.js.map} +1 -1
  91. package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js → AgentsPage-BA_ai9HJ.js} +2 -2
  92. package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js.map → AgentsPage-BA_ai9HJ.js.map} +1 -1
  93. package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js → AvailableEscalationsPage-C2_5aEFW.js} +2 -2
  94. package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js.map → AvailableEscalationsPage-C2_5aEFW.js.map} +1 -1
  95. package/dashboard/dist/assets/{BotPicker-CGB16rYU.js → BotPicker-BZo4Kp4a.js} +2 -2
  96. package/dashboard/dist/assets/{BotPicker-CGB16rYU.js.map → BotPicker-BZo4Kp4a.js.map} +1 -1
  97. package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js → BulkAssignModal-BFhyxY2T.js} +2 -2
  98. package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js.map → BulkAssignModal-BFhyxY2T.js.map} +1 -1
  99. package/dashboard/dist/assets/CapabilitiesPage-CvOX6vAc.js +2 -0
  100. package/dashboard/dist/assets/{CapabilitiesPage-BxadotXn.js.map → CapabilitiesPage-CvOX6vAc.js.map} +1 -1
  101. package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js → CollapsibleSection-GCJsV9Oq.js} +2 -2
  102. package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js.map → CollapsibleSection-GCJsV9Oq.js.map} +1 -1
  103. package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js → ConfirmDeleteModal-CAgYLcef.js} +2 -2
  104. package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js.map → ConfirmDeleteModal-CAgYLcef.js.map} +1 -1
  105. package/dashboard/dist/assets/CountdownTimer-Dik2z0M_.js +2 -0
  106. package/dashboard/dist/assets/{CountdownTimer-CI_JOAvk.js.map → CountdownTimer-Dik2z0M_.js.map} +1 -1
  107. package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js → CredentialsPage-twd2xCOW.js} +2 -2
  108. package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js.map → CredentialsPage-twd2xCOW.js.map} +1 -1
  109. package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js → CronLabel-DdnIuudX.js} +2 -2
  110. package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js.map → CronLabel-DdnIuudX.js.map} +1 -1
  111. package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js → ElapsedCell-DCctVv5R.js} +2 -2
  112. package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js.map → ElapsedCell-DCctVv5R.js.map} +1 -1
  113. package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js → EntityTimelinePanel-CMnskyWv.js} +2 -2
  114. package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js.map → EntityTimelinePanel-CMnskyWv.js.map} +1 -1
  115. package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js → EscalationListSchemaPage-VfCn6WDb.js} +3 -3
  116. package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js.map → EscalationListSchemaPage-VfCn6WDb.js.map} +1 -1
  117. package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js → EscalationListView-CGQZxcC-.js} +2 -2
  118. package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js.map → EscalationListView-CGQZxcC-.js.map} +1 -1
  119. package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js → EscalationSchemaPage-BX0tx-PM.js} +3 -3
  120. package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js.map → EscalationSchemaPage-BX0tx-PM.js.map} +1 -1
  121. package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js → EscalationTimeline-DKoSM56J.js} +2 -2
  122. package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js.map → EscalationTimeline-DKoSM56J.js.map} +1 -1
  123. package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js → EscalationTitleSelect-DWGLBOmS.js} +2 -2
  124. package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js.map → EscalationTitleSelect-DWGLBOmS.js.map} +1 -1
  125. package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js → EscalationsOverview-C2XoguaA.js} +2 -2
  126. package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js.map → EscalationsOverview-C2XoguaA.js.map} +1 -1
  127. package/dashboard/dist/assets/{EventTable-DSHqKyX2.js → EventTable-CBUWq7--.js} +2 -2
  128. package/dashboard/dist/assets/{EventTable-DSHqKyX2.js.map → EventTable-CBUWq7--.js.map} +1 -1
  129. package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js → FilterBar-8IdbleZ9.js} +2 -2
  130. package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js.map → FilterBar-8IdbleZ9.js.map} +1 -1
  131. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js +2 -0
  132. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js.map +1 -0
  133. package/dashboard/dist/assets/{GraphInvokePage-ChqqGkro.js → GraphInvokePage-CUvoPzsW.js} +2 -2
  134. package/dashboard/dist/assets/{GraphInvokePage-ChqqGkro.js.map → GraphInvokePage-CUvoPzsW.js.map} +1 -1
  135. package/dashboard/dist/assets/{HomePage-ByKesG8w.js → HomePage-BP7v9GLJ.js} +2 -2
  136. package/dashboard/dist/assets/{HomePage-ByKesG8w.js.map → HomePage-BP7v9GLJ.js.map} +1 -1
  137. package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js → ListToolbar-Cnacuwoy.js} +2 -2
  138. package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js.map → ListToolbar-Cnacuwoy.js.map} +1 -1
  139. package/dashboard/dist/assets/{McpOverview-CVe13tEv.js → McpOverview-C2JoNoDA.js} +2 -2
  140. package/dashboard/dist/assets/{McpOverview-CVe13tEv.js.map → McpOverview-C2JoNoDA.js.map} +1 -1
  141. package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js → McpQueryDetailPage-C_nih0w-.js} +2 -2
  142. package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js.map → McpQueryDetailPage-C_nih0w-.js.map} +1 -1
  143. package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js → McpQueryPage-U_wNXow2.js} +2 -2
  144. package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js.map → McpQueryPage-U_wNXow2.js.map} +1 -1
  145. package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js → McpRunDetailPage-DtKoJq6J.js} +2 -2
  146. package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js.map → McpRunDetailPage-DtKoJq6J.js.map} +1 -1
  147. package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js → McpRunsPage-CnYtfGhf.js} +2 -2
  148. package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js.map → McpRunsPage-CnYtfGhf.js.map} +1 -1
  149. package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js → OperationsPage-C7hupIer.js} +2 -2
  150. package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js.map → OperationsPage-C7hupIer.js.map} +1 -1
  151. package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js → OperatorDashboard-fVuLn2D5.js} +2 -2
  152. package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js.map → OperatorDashboard-fVuLn2D5.js.map} +1 -1
  153. package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js → PersonaDetailPage-C-4o8lPw.js} +2 -2
  154. package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js.map → PersonaDetailPage-C-4o8lPw.js.map} +1 -1
  155. package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js → PersonasPage-BL1FwLmv.js} +2 -2
  156. package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js.map → PersonasPage-BL1FwLmv.js.map} +1 -1
  157. package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js → PortalPage-tJG5sgb1.js} +2 -2
  158. package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js.map → PortalPage-tJG5sgb1.js.map} +1 -1
  159. package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js → ProcessDetailPage-Dz_jY4Yt.js} +2 -2
  160. package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js.map → ProcessDetailPage-Dz_jY4Yt.js.map} +1 -1
  161. package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js → ProcessesListPage-Cbn9cter.js} +2 -2
  162. package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js.map → ProcessesListPage-Cbn9cter.js.map} +1 -1
  163. package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js +8 -0
  164. package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js.map +1 -0
  165. package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js +8 -0
  166. package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js.map +1 -0
  167. package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js → RolesPage-NwmMvZFa.js} +2 -2
  168. package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js.map → RolesPage-NwmMvZFa.js.map} +1 -1
  169. package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js → RunAsSelector-tgEooTyU.js} +2 -2
  170. package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js.map → RunAsSelector-tgEooTyU.js.map} +1 -1
  171. package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js +2 -0
  172. package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js.map +1 -0
  173. package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js +2 -0
  174. package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js.map +1 -0
  175. package/dashboard/dist/assets/ScanStationPage-B275l6r_.js +2 -0
  176. package/dashboard/dist/assets/ScanStationPage-B275l6r_.js.map +1 -0
  177. package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js → StickyPagination-CsTI_gvJ.js} +2 -2
  178. package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js.map → StickyPagination-CsTI_gvJ.js.map} +1 -1
  179. package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js → StreamMessageDetail-auRlvjTh.js} +2 -2
  180. package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js.map → StreamMessageDetail-auRlvjTh.js.map} +1 -1
  181. package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js → SwimlaneTimeline-BLoVHYAd.js} +2 -2
  182. package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js.map → SwimlaneTimeline-BLoVHYAd.js.map} +1 -1
  183. package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js → TaskDetailPage-BPsZ1bK_.js} +2 -2
  184. package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js.map → TaskDetailPage-BPsZ1bK_.js.map} +1 -1
  185. package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js → TasksListPage-BNGM74yT.js} +2 -2
  186. package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js.map → TasksListPage-BNGM74yT.js.map} +1 -1
  187. package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js → TimeAgo-BnAHXGK7.js} +2 -2
  188. package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js.map → TimeAgo-BnAHXGK7.js.map} +1 -1
  189. package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js → TimestampCell-J4yae6mc.js} +2 -2
  190. package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js.map → TimestampCell-J4yae6mc.js.map} +1 -1
  191. package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js → ToolTestPanel-BdzzgXDu.js} +2 -2
  192. package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js.map → ToolTestPanel-BdzzgXDu.js.map} +1 -1
  193. package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js → TopicDetailPage-DJKg8lb7.js} +2 -2
  194. package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js.map → TopicDetailPage-DJKg8lb7.js.map} +1 -1
  195. package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js → TopicsPage-DQV0WxG6.js} +2 -2
  196. package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js.map → TopicsPage-DQV0WxG6.js.map} +1 -1
  197. package/dashboard/dist/assets/{UserName-CXsdPiMZ.js → UserName-Ct09nGh5.js} +2 -2
  198. package/dashboard/dist/assets/{UserName-CXsdPiMZ.js.map → UserName-Ct09nGh5.js.map} +1 -1
  199. package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js → WorkflowExecutionPage-B5WJOsee.js} +2 -2
  200. package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js.map → WorkflowExecutionPage-B5WJOsee.js.map} +1 -1
  201. package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js → WorkflowsDashboard-Hc87TRgD.js} +2 -2
  202. package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js.map → WorkflowsDashboard-Hc87TRgD.js.map} +1 -1
  203. package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js → WorkflowsOverview-CJQbyOj-.js} +2 -2
  204. package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js.map → WorkflowsOverview-CJQbyOj-.js.map} +1 -1
  205. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js → YamlWorkflowDetailPage-BMeED677.js} +8 -8
  206. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js.map → YamlWorkflowDetailPage-BMeED677.js.map} +1 -1
  207. package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js → YamlWorkflowsPage-BMMg0Id6.js} +2 -2
  208. package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js.map → YamlWorkflowsPage-BMMg0Id6.js.map} +1 -1
  209. package/dashboard/dist/assets/{agents-v_HH3Rji.js → agents-CdFkgFvg.js} +2 -2
  210. package/dashboard/dist/assets/{agents-v_HH3Rji.js.map → agents-CdFkgFvg.js.map} +1 -1
  211. package/dashboard/dist/assets/{bots-bwvWYrXz.js → bots-Mj3LHWWg.js} +2 -2
  212. package/dashboard/dist/assets/{bots-bwvWYrXz.js.map → bots-Mj3LHWWg.js.map} +1 -1
  213. package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js → capabilities-Dw1ObK2-.js} +2 -2
  214. package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js.map → capabilities-Dw1ObK2-.js.map} +1 -1
  215. package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js → controlplane-DcNE1APv.js} +2 -2
  216. package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js.map → controlplane-DcNE1APv.js.map} +1 -1
  217. package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js → escalation-columns-D364Trpy.js} +2 -2
  218. package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js.map → escalation-columns-D364Trpy.js.map} +1 -1
  219. package/dashboard/dist/assets/{index-IJmtbuLh.js → index-B3veJ698.js} +2 -2
  220. package/dashboard/dist/assets/{index-IJmtbuLh.js.map → index-B3veJ698.js.map} +1 -1
  221. package/dashboard/dist/assets/index-BQeHJHYN.js +67 -0
  222. package/dashboard/dist/assets/index-BQeHJHYN.js.map +1 -0
  223. package/dashboard/dist/assets/{index-D2VKBMng.js → index-BRGTmoYY.js} +2 -2
  224. package/dashboard/dist/assets/{index-D2VKBMng.js.map → index-BRGTmoYY.js.map} +1 -1
  225. package/dashboard/dist/assets/{index-C4Lce2ET.js → index-Bd6-KmBE.js} +3 -3
  226. package/dashboard/dist/assets/{index-C4Lce2ET.js.map → index-Bd6-KmBE.js.map} +1 -1
  227. package/dashboard/dist/assets/{index-CcuvGdvf.js → index-BiVce3n0.js} +2 -2
  228. package/dashboard/dist/assets/{index-CcuvGdvf.js.map → index-BiVce3n0.js.map} +1 -1
  229. package/dashboard/dist/assets/{index-D6pBLZFu.js → index-BmNAVd4s.js} +2 -2
  230. package/dashboard/dist/assets/{index-D6pBLZFu.js.map → index-BmNAVd4s.js.map} +1 -1
  231. package/dashboard/dist/assets/{index-CjenRVX_.js → index-Bq5XNEzD.js} +2 -2
  232. package/dashboard/dist/assets/{index-CjenRVX_.js.map → index-Bq5XNEzD.js.map} +1 -1
  233. package/dashboard/dist/assets/{index-CzjUgFt_.js → index-DPStdq4T.js} +2 -2
  234. package/dashboard/dist/assets/{index-CzjUgFt_.js.map → index-DPStdq4T.js.map} +1 -1
  235. package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
  236. package/dashboard/dist/assets/{index-C3WutFpT.js → index-DkcI4V_H.js} +2 -2
  237. package/dashboard/dist/assets/{index-C3WutFpT.js.map → index-DkcI4V_H.js.map} +1 -1
  238. package/dashboard/dist/assets/{index-2tzsxFat.js → index-Dyotfa_k.js} +2 -2
  239. package/dashboard/dist/assets/{index-2tzsxFat.js.map → index-Dyotfa_k.js.map} +1 -1
  240. package/dashboard/dist/assets/{index-C_ISDOWJ.js → index-MDD4JYtu.js} +2 -2
  241. package/dashboard/dist/assets/{index-C_ISDOWJ.js.map → index-MDD4JYtu.js.map} +1 -1
  242. package/dashboard/dist/assets/index-WSm8bgE7.js +3 -0
  243. package/dashboard/dist/assets/index-WSm8bgE7.js.map +1 -0
  244. package/dashboard/dist/assets/{index-BLB77tc8.js → index-eDm6cz0F.js} +2 -2
  245. package/dashboard/dist/assets/{index-BLB77tc8.js.map → index-eDm6cz0F.js.map} +1 -1
  246. package/dashboard/dist/assets/{knowledge-D1YP2NzS.js → knowledge-Bafewjxk.js} +2 -2
  247. package/dashboard/dist/assets/{knowledge-D1YP2NzS.js.map → knowledge-Bafewjxk.js.map} +1 -1
  248. package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js → mcp-query-BzTtIG90.js} +2 -2
  249. package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js.map → mcp-query-BzTtIG90.js.map} +1 -1
  250. package/dashboard/dist/assets/{mcp-Bb5psC61.js → mcp-vLIutbnc.js} +2 -2
  251. package/dashboard/dist/assets/{mcp-Bb5psC61.js.map → mcp-vLIutbnc.js.map} +1 -1
  252. package/dashboard/dist/assets/{personas-CDndbkp4.js → personas-WD40EDS_.js} +2 -2
  253. package/dashboard/dist/assets/{personas-CDndbkp4.js.map → personas-WD40EDS_.js.map} +1 -1
  254. package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js → pipelines-DFwULWs3.js} +2 -2
  255. package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js.map → pipelines-DFwULWs3.js.map} +1 -1
  256. package/dashboard/dist/assets/{tasks-BlpDsWCy.js → tasks-La_-WAUn.js} +2 -2
  257. package/dashboard/dist/assets/{tasks-BlpDsWCy.js.map → tasks-La_-WAUn.js.map} +1 -1
  258. package/dashboard/dist/assets/{topics-C0YaR9fu.js → topics-CzYMlvqm.js} +2 -2
  259. package/dashboard/dist/assets/{topics-C0YaR9fu.js.map → topics-CzYMlvqm.js.map} +1 -1
  260. package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js → useDebouncedValue-C0FQyANW.js} +2 -2
  261. package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js.map → useDebouncedValue-C0FQyANW.js.map} +1 -1
  262. package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js → useNamespace-WW_XjAb3.js} +2 -2
  263. package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js.map → useNamespace-WW_XjAb3.js.map} +1 -1
  264. package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js → useYamlActivityEvents-B3YxPeFt.js} +2 -2
  265. package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js.map → useYamlActivityEvents-B3YxPeFt.js.map} +1 -1
  266. package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js → yaml-workflows-COHOjdhF.js} +2 -2
  267. package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js.map → yaml-workflows-COHOjdhF.js.map} +1 -1
  268. package/dashboard/dist/index.html +2 -2
  269. package/docs/dashboard.md +1 -1
  270. package/docs/hitl/x-lt-scan.md +51 -0
  271. package/docs/hitl-guide.md +2 -0
  272. package/docs/scan-codes.md +221 -21
  273. package/package.json +1 -1
  274. package/build/types/scan-code.d.ts +0 -317
  275. package/dashboard/dist/assets/CapabilitiesPage-BxadotXn.js +0 -2
  276. package/dashboard/dist/assets/CountdownTimer-CI_JOAvk.js +0 -2
  277. package/dashboard/dist/assets/ResolverForm-BVG8X0sS.js +0 -8
  278. package/dashboard/dist/assets/ResolverForm-BVG8X0sS.js.map +0 -1
  279. package/dashboard/dist/assets/RoleDetailPage-KCXDqoJz.js +0 -8
  280. package/dashboard/dist/assets/RoleDetailPage-KCXDqoJz.js.map +0 -1
  281. package/dashboard/dist/assets/ScanCodesPage-CUhCz-Yr.js +0 -2
  282. package/dashboard/dist/assets/ScanCodesPage-CUhCz-Yr.js.map +0 -1
  283. package/dashboard/dist/assets/ScanSchemeDetailPage-qzXKNqJK.js +0 -2
  284. package/dashboard/dist/assets/ScanSchemeDetailPage-qzXKNqJK.js.map +0 -1
  285. package/dashboard/dist/assets/ScanStationPage-D8e8cG3t.js +0 -2
  286. package/dashboard/dist/assets/ScanStationPage-D8e8cG3t.js.map +0 -1
  287. package/dashboard/dist/assets/index-CT-FN6CW.js +0 -3
  288. package/dashboard/dist/assets/index-CT-FN6CW.js.map +0 -1
  289. package/dashboard/dist/assets/index-Dh8MJl3L.css +0 -1
  290. package/dashboard/dist/assets/index-N71QQ3J5.js +0 -67
  291. 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): Promise<LTApiResult<ScanExecuteResponse>>;
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
- const user = await userService.getUserByMetadataValue(scheme.target_facet, parsed.target);
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: 'badge not recognized',
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: scheme.grant_ttl_seconds ?? undefined,
84
- maxUses: scheme.grant_max_uses,
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() + (scheme.grant_ttl_seconds ?? 0) * 1000).toISOString();
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: scheme.grant_max_uses ?? 0,
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 {};