@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,152 @@
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.fillStep = fillStep;
37
+ const scanCodeService = __importStar(require("../../services/scan-code"));
38
+ const escalationService = __importStar(require("../../services/escalation"));
39
+ const resolve_batch_1 = require("../escalations/resolve-batch");
40
+ const escalation_1 = require("../../types/escalation");
41
+ const types_1 = require("../../types");
42
+ const context_1 = require("./context");
43
+ const grant_1 = require("./grant");
44
+ const locate_1 = require("./locate");
45
+ const subject_1 = require("./subject");
46
+ const STOCK_UNEXPECTED = 'Not one of the items expected here.';
47
+ function readBatch(row) {
48
+ const meta = (row.metadata ?? {});
49
+ const pending = meta[escalation_1.ESCALATION_BATCH_KEYS.PENDING];
50
+ const keys = meta[escalation_1.ESCALATION_BATCH_KEYS.KEYS];
51
+ if (!Array.isArray(pending))
52
+ return null;
53
+ return { pending: pending.map(String), keys: Array.isArray(keys) ? keys.map(String) : pending.map(String) };
54
+ }
55
+ /** The code a batch key names, without its ordinal suffix. */
56
+ function codeOf(key, separator) {
57
+ const at = key.lastIndexOf(separator);
58
+ return at > 0 && /^[0-9]+$/.test(key.slice(at + 1)) ? key.slice(0, at) : key;
59
+ }
60
+ function keysFor(keys, target, separator) {
61
+ return keys.filter((k) => codeOf(k, separator) === target);
62
+ }
63
+ function progress(batch, filledNow) {
64
+ const remaining = Math.max(0, batch.pending.length - filledNow);
65
+ return { filled: batch.keys.length - remaining, total: batch.keys.length, remaining };
66
+ }
67
+ async function fillStep(step, ctx) {
68
+ const options = step.params.fill;
69
+ const separator = options.separator ?? types_1.SCAN_FILL_SEPARATOR_DEFAULT;
70
+ // 1. The batch row: the held subject, or the row the scan names
71
+ const row = options.into === 'subject'
72
+ ? ctx.subject.row
73
+ : (await (0, locate_1.locateForStep)(step, ctx, 1))?.escalations[0];
74
+ if (!row)
75
+ return null;
76
+ if (options.into === 'subject' && step.subject?.claimedByOther !== 'allow') {
77
+ const other = await (0, subject_1.claimedByOther)(row, ctx.auth.userId);
78
+ if (other)
79
+ return (0, context_1.refused)(`Claimed by **${other.displayName}**.`);
80
+ }
81
+ const batch = readBatch(row);
82
+ if (!batch)
83
+ return (0, context_1.conflict)('the held row is not a batch');
84
+ // 2. Which open slot this scan fills, or why none
85
+ const tpl = {
86
+ ...(0, context_1.templateContext)(ctx),
87
+ fill: {
88
+ pending: [...new Set(batch.pending.map((k) => codeOf(k, separator)))],
89
+ total: batch.keys.length,
90
+ filled: batch.keys.length - batch.pending.length,
91
+ },
92
+ };
93
+ const candidates = keysFor(batch.pending, ctx.parsed.target, separator);
94
+ if (candidates.length === 0) {
95
+ const declared = keysFor(batch.keys, ctx.parsed.target, separator);
96
+ const markdown = declared.length
97
+ ? `All ${declared.length} of these are already checked off.`
98
+ : scanCodeService.renderScanCopy(step.refuse?.markdown ?? STOCK_UNEXPECTED, tpl);
99
+ return (0, context_1.refused)(markdown, {
100
+ refusal: { markdown, expected: tpl.fill.pending },
101
+ progress: progress(batch, 0),
102
+ });
103
+ }
104
+ // 3. Spend the badge, then fill; a slot taken since the read moves to the next
105
+ let payload;
106
+ try {
107
+ payload = scanCodeService.interpolateScanTemplate(options.payload ?? { scannedCode: '{scan.code}' }, tpl);
108
+ }
109
+ catch (err) {
110
+ if (err instanceof scanCodeService.ScanTemplateError)
111
+ return null;
112
+ throw err;
113
+ }
114
+ const notPrimed = (await (0, grant_1.identityGate)(step, ctx)) ?? (await (0, grant_1.spendGrant)(ctx));
115
+ if (notPrimed)
116
+ return notPrimed;
117
+ for (const itemKey of candidates) {
118
+ const result = await (0, resolve_batch_1.resolveBatchItem)({
119
+ id: row.id, itemKey, resolverPayload: payload, metadata: (0, context_1.provenance)(ctx),
120
+ }, ctx.auth);
121
+ if (result.status === 200) {
122
+ const data = result.data;
123
+ const done = data.outcome === 'completed';
124
+ const filled = progress(batch, batch.pending.length - (done ? 0 : (data.remaining ?? 0)));
125
+ return (0, context_1.withDone)({
126
+ status: 200,
127
+ data: {
128
+ outcome: types_1.SCAN_OUTCOMES.EXECUTED,
129
+ verb: step.verb,
130
+ escalation: { id: row.id, ...data },
131
+ progress: filled,
132
+ ...(done ? { clearSubject: true } : {}),
133
+ },
134
+ }, step, { ...tpl, fill: { ...tpl.fill, ...filled } });
135
+ }
136
+ const outcome = result.data?.outcome;
137
+ if (outcome === 'duplicate-item')
138
+ continue;
139
+ if (result.status === 403)
140
+ return (0, context_1.forbidden)(result.error);
141
+ if (result.status === 404)
142
+ return null;
143
+ if (outcome?.startsWith('already-'))
144
+ return (0, context_1.refused)('This one is already complete.', { clearSubject: true });
145
+ return (0, context_1.refused)(result.error ?? STOCK_UNEXPECTED);
146
+ }
147
+ const fresh = await escalationService.getEscalation(row.id);
148
+ const after = fresh ? readBatch(fresh) : null;
149
+ return (0, context_1.refused)(`All ${keysFor(batch.keys, ctx.parsed.target, separator).length} of these are already checked off.`, {
150
+ ...(after ? { progress: progress(after, 0) } : {}),
151
+ });
152
+ }
@@ -0,0 +1,14 @@
1
+ import { type LTEscalationRecord, 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
+ /**
6
+ * The pre-write guard. Returns the refusal when the pairing is wrong, null
7
+ * when it holds (or the step declares no match).
8
+ */
9
+ export declare function matchGuard(step: ScanStep, ctx: StepContext, container?: LTEscalationRecord): ScanResult | null;
10
+ /** The subject joins the scanned container; the subject's row is the reciprocal. */
11
+ export declare function accumulateFromSubject(step: ScanStep, ctx: StepContext): Promise<ScanResult | null>;
12
+ /** The subject's own row collects the scanned code. */
13
+ export declare function accumulateIntoSubject(step: ScanStep, ctx: StepContext): Promise<ScanResult | null>;
14
+ export {};
@@ -0,0 +1,270 @@
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.matchGuard = matchGuard;
37
+ exports.accumulateFromSubject = accumulateFromSubject;
38
+ exports.accumulateIntoSubject = accumulateIntoSubject;
39
+ const scanCodeService = __importStar(require("../../services/scan-code"));
40
+ const escalationService = __importStar(require("../../services/escalation"));
41
+ const accumulate_1 = require("../escalations/accumulate");
42
+ const helpers_1 = require("../escalations/helpers");
43
+ const metadata_1 = require("../escalations/metadata");
44
+ const escalation_1 = require("../../types/escalation");
45
+ const types_1 = require("../../types");
46
+ const context_1 = require("./context");
47
+ const grant_1 = require("./grant");
48
+ const subject_1 = require("./subject");
49
+ // ── Acting on the held subject ──────────────────────────────────────────────
50
+ //
51
+ // The station holds an item; this scan names where it goes. The step checks
52
+ // the pairing first (match), refusing with nothing written when it is wrong,
53
+ // then writes by id in one atomic statement: the subject joins the scanned
54
+ // container with its own row as the reciprocal (from: 'subject'), or the
55
+ // subject's row collects the scanned code (into: 'subject').
56
+ const STOCK_REFUSAL = 'That is not where this one goes.';
57
+ const STOCK_CONFLICT = 'That container just closed. Scan it again, or the next one.';
58
+ const STOCK_PLACED = 'This one is already placed.';
59
+ /** The step's template bags with the subject (and the container, once located). */
60
+ function bags(ctx, container) {
61
+ return { ...(0, context_1.templateContext)(ctx), ...(container ? { container: container.metadata ?? {} } : {}) };
62
+ }
63
+ /** Refuse the act when someone else holds a live claim on the subject. */
64
+ async function claimGuard(step, ctx, subject) {
65
+ if (step.subject?.claimedByOther === 'allow')
66
+ return null;
67
+ const other = await (0, subject_1.claimedByOther)(subject.row, ctx.auth.userId);
68
+ return other ? (0, context_1.refused)(`Claimed by **${other.displayName}**.`) : null;
69
+ }
70
+ /** The container the scan names: a pending accumulator under the actor's read scope. */
71
+ async function locateContainer(step, ctx) {
72
+ const selector = step.params?.accumulate?.container;
73
+ const scope = await (0, helpers_1.getEscalationReadScope)(ctx.auth.userId);
74
+ const roles = (0, metadata_1.restrictScopeRoles)(scope.allRoles, scope.global, selector?.roles ?? step.query?.roles);
75
+ if (roles !== null && roles.length === 0)
76
+ return null;
77
+ const found = await escalationService.searchByFacets({
78
+ roles: roles ?? undefined,
79
+ types: selector?.types,
80
+ subtypes: selector?.subtypes,
81
+ facets: { ...selector?.facets, [ctx.scheme.target_facet]: ctx.parsed.target },
82
+ status: 'pending',
83
+ exists: [escalation_1.ESCALATION_ACCUMULATE_KEYS.COUNT],
84
+ limit: 2,
85
+ });
86
+ return found.escalations.filter((row) => row.id !== ctx.subject?.row.id);
87
+ }
88
+ const WHOLE_BAG_TOKEN = /^\{(subject|container)\.([a-zA-Z0-9_]+)\}$/;
89
+ /**
90
+ * One match.target template as the values it allows. A template that is a
91
+ * single bag token naming a list facet (`{subject.offeredContainers}`) allows every
92
+ * entry; anything else renders to one value. A token with nothing to read
93
+ * allows nothing.
94
+ */
95
+ function expandTarget(template, tpl) {
96
+ const whole = template.match(WHOLE_BAG_TOKEN);
97
+ if (whole) {
98
+ const value = tpl[whole[1]]?.[whole[2]];
99
+ if (Array.isArray(value))
100
+ return value.filter((v) => v !== null && v !== '').map(String);
101
+ }
102
+ try {
103
+ return [scanCodeService.interpolateScanTemplate(template, tpl)];
104
+ }
105
+ catch {
106
+ return [];
107
+ }
108
+ }
109
+ /**
110
+ * The pre-write guard. Returns the refusal when the pairing is wrong, null
111
+ * when it holds (or the step declares no match).
112
+ */
113
+ function matchGuard(step, ctx, container) {
114
+ const match = step.match;
115
+ if (!match)
116
+ return null;
117
+ const tpl = bags(ctx, container);
118
+ const expected = (match.target ?? []).flatMap((t) => expandTarget(t, tpl));
119
+ const targetOk = match.target === undefined || expected.includes(ctx.parsed.target);
120
+ const subjectMeta = (ctx.subject?.row.metadata ?? {});
121
+ const containerMeta = (container?.metadata ?? {});
122
+ // With no container located there is nothing to compare; the step falls through.
123
+ const facetsOk = match.facets === undefined || !container || (match.facets.every((f) => subjectMeta[f] !== undefined && subjectMeta[f] !== null && String(subjectMeta[f]) === String(containerMeta[f])));
124
+ if (targetOk && facetsOk)
125
+ return null;
126
+ const markdown = scanCodeService.renderScanCopy(step.refuse?.markdown ?? STOCK_REFUSAL, tpl);
127
+ return (0, context_1.refused)(markdown, { refusal: { markdown, ...(expected.length ? { expected } : {}) } });
128
+ }
129
+ /** Map a failed add onto what the bench says. 404 falls through. */
130
+ function failedAdd(step, ctx, result, container) {
131
+ const outcome = result.data?.outcome;
132
+ if (result.status === 404)
133
+ return null;
134
+ if (result.status === 403)
135
+ return (0, context_1.forbidden)(result.error);
136
+ if (outcome === 'reciprocal-terminal' || outcome === 'reciprocal-full' || outcome === 'reciprocal-duplicate') {
137
+ return (0, context_1.refused)(STOCK_PLACED, { clearSubject: true });
138
+ }
139
+ if (outcome === 'claimed-by-other' || outcome === 'claim-expired')
140
+ return (0, context_1.conflict)(result.error);
141
+ if (result.status === 409) {
142
+ const markdown = scanCodeService.renderScanCopy(step.refuse?.conflict ?? STOCK_CONFLICT, bags(ctx, container));
143
+ // A lost race for a shared container: the subject's offer may have moved, so drop it.
144
+ return (0, context_1.refused)(markdown, { clearSubject: !!step.refuse?.conflict });
145
+ }
146
+ return (0, context_1.refused)(result.error ?? STOCK_REFUSAL);
147
+ }
148
+ function rendered(step, ctx, itemKeyDefault) {
149
+ const tpl = (0, context_1.templateContext)(ctx);
150
+ try {
151
+ return {
152
+ itemKey: scanCodeService.interpolateScanTemplate(step.params?.itemKey ?? itemKeyDefault ?? '', tpl),
153
+ payload: step.params?.resolverPayload
154
+ ? scanCodeService.interpolateScanTemplate(step.params.resolverPayload, tpl)
155
+ : undefined,
156
+ metadata: {
157
+ ...(step.params?.metadata ? scanCodeService.interpolateScanTemplate(step.params.metadata, tpl) : {}),
158
+ ...(0, context_1.provenance)(ctx),
159
+ },
160
+ };
161
+ }
162
+ catch (err) {
163
+ if (err instanceof scanCodeService.ScanTemplateError)
164
+ return null;
165
+ throw err;
166
+ }
167
+ }
168
+ /** The subject joins the scanned container; the subject's row is the reciprocal. */
169
+ async function accumulateFromSubject(step, ctx) {
170
+ const subject = ctx.subject;
171
+ const claimed = await claimGuard(step, ctx, subject);
172
+ if (claimed)
173
+ return claimed;
174
+ // 1. Locate the container the scan names
175
+ const containers = await locateContainer(step, ctx);
176
+ if (containers && containers.length > 1) {
177
+ return (0, context_1.conflict)(`more than one open container carries ${ctx.scheme.target_facet} = ${ctx.parsed.target}`);
178
+ }
179
+ const container = containers?.[0];
180
+ // 2. Check the pairing before anything is written
181
+ const mismatch = matchGuard(step, ctx, container);
182
+ if (mismatch)
183
+ return mismatch;
184
+ if (!container) {
185
+ if (!step.refuse?.missing)
186
+ return null;
187
+ return (0, context_1.refused)(scanCodeService.renderScanCopy(step.refuse.missing, bags(ctx)));
188
+ }
189
+ // 3. Spend the badge, then write both rows in one statement
190
+ const values = rendered(step, ctx);
191
+ if (!values)
192
+ return null;
193
+ const notPrimed = (await (0, grant_1.identityGate)(step, ctx)) ?? (await (0, grant_1.spendGrant)(ctx));
194
+ if (notPrimed)
195
+ return notPrimed;
196
+ const result = await (0, accumulate_1.accumulateItem)({
197
+ id: container.id,
198
+ itemKey: values.itemKey,
199
+ payload: values.payload,
200
+ metadata: values.metadata,
201
+ reciprocal: { id: subject.row.id },
202
+ }, ctx.auth);
203
+ // 4. Report
204
+ if (result.status !== 200) {
205
+ if (result.data?.outcome === 'duplicate-item') {
206
+ return already(step, container);
207
+ }
208
+ return failedAdd(step, ctx, result, container);
209
+ }
210
+ return (0, context_1.withDone)({
211
+ status: 200,
212
+ data: {
213
+ outcome: types_1.SCAN_OUTCOMES.EXECUTED,
214
+ verb: step.verb,
215
+ escalation: { id: container.id, ...result.data },
216
+ clearSubject: true,
217
+ },
218
+ }, step, bags(ctx, container));
219
+ }
220
+ /** The subject's own row collects the scanned code. */
221
+ async function accumulateIntoSubject(step, ctx) {
222
+ const subject = ctx.subject;
223
+ const claimed = await claimGuard(step, ctx, subject);
224
+ if (claimed)
225
+ return claimed;
226
+ const mismatch = matchGuard(step, ctx);
227
+ if (mismatch)
228
+ return mismatch;
229
+ const values = rendered(step, ctx, '{scan.target}');
230
+ if (!values)
231
+ return null;
232
+ const notPrimed = (await (0, grant_1.identityGate)(step, ctx)) ?? (await (0, grant_1.spendGrant)(ctx));
233
+ if (notPrimed)
234
+ return notPrimed;
235
+ const result = await (0, accumulate_1.accumulateItem)({
236
+ id: subject.row.id,
237
+ itemKey: values.itemKey,
238
+ payload: values.payload,
239
+ metadata: values.metadata,
240
+ }, ctx.auth);
241
+ if (result.status !== 200) {
242
+ if (result.data?.outcome === 'duplicate-item') {
243
+ return already(step, subject.row);
244
+ }
245
+ return failedAdd(step, ctx, result);
246
+ }
247
+ const data = result.data;
248
+ return (0, context_1.withDone)({
249
+ status: 200,
250
+ data: {
251
+ outcome: types_1.SCAN_OUTCOMES.EXECUTED,
252
+ verb: step.verb,
253
+ escalation: { id: subject.row.id, ...result.data },
254
+ clearSubject: data.outcome === 'completed',
255
+ },
256
+ }, step, bags(ctx));
257
+ }
258
+ /** The item is already where the scan says: harmless, nothing written. */
259
+ function already(step, row) {
260
+ return {
261
+ status: 200,
262
+ data: {
263
+ outcome: types_1.SCAN_OUTCOMES.EXECUTED,
264
+ verb: step.verb,
265
+ escalation: { id: row.id },
266
+ already: true,
267
+ clearSubject: true,
268
+ },
269
+ };
270
+ }
@@ -18,24 +18,4 @@ export declare function releaseStep(step: ScanStep, ctx: StepContext): Promise<L
18
18
  */
19
19
  export declare function dispatchChoiceVerb(step: ScanStep, ctx: StepContext, row: Record<string, any>): Promise<LTApiResult<ScanExecuteResponse>>;
20
20
  export declare function cancelStep(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
21
- /**
22
- * Adds the scanned item to an accumulator. Two modes, one atomic write:
23
- *
24
- * - Item-locate (`params.accumulate.containerFacet`): the scan locates the
25
- * item's own pending row through the scheme facet, reads the container
26
- * facet value it carries, and adds the target to the container that shares
27
- * it, writing the item row as the reciprocal in the same statement. An
28
- * item with no row, or no container facet, falls through. An item whose
29
- * container has closed and whose successor has not parked yet answers
30
- * `no_open_container` with the item row, so the station can say "scan
31
- * again" instead of showing the bag with no hint.
32
- * - Container-locate (no `containerFacet`): the scan locates the container
33
- * by the scheme facet and adds `params.itemKey` (template).
34
- *
35
- * Templates may read `{claim.<facet>}` (the actor's live claim) and, in item
36
- * mode, `{item.<facet>}` (the located row); an unresolvable token falls
37
- * through. The write is the SDK's guarded statement; the locate only picks
38
- * ids. A container already holding the item answers conflict, never a
39
- * second add.
40
- */
41
- export declare function accumulateStep(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
21
+ export { accumulateStep } from './verb-accumulate';
@@ -33,46 +33,34 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.accumulateStep = void 0;
36
37
  exports.claimStep = claimStep;
37
38
  exports.resolveStep = resolveStep;
38
39
  exports.escalateStep = escalateStep;
39
40
  exports.releaseStep = releaseStep;
40
41
  exports.dispatchChoiceVerb = dispatchChoiceVerb;
41
42
  exports.cancelStep = cancelStep;
42
- exports.accumulateStep = accumulateStep;
43
43
  const scanCodeService = __importStar(require("../../services/scan-code"));
44
44
  const escalationService = __importStar(require("../../services/escalation"));
45
45
  const metadata_1 = require("../escalations/metadata");
46
- const accumulate_1 = require("../escalations/accumulate");
47
46
  const create_1 = require("../escalations/create");
48
47
  const claim_1 = require("../escalations/claim");
49
48
  const helpers_1 = require("../escalations/helpers");
50
49
  const types_1 = require("../../types");
51
50
  const context_1 = require("./context");
52
- const locate_1 = require("./locate");
51
+ const grant_1 = require("./grant");
52
+ const hold_1 = require("./hold");
53
53
  // ── Mutating verbs — each a single atomic operation under the ACTOR's RBAC ──
54
54
  // ctx.auth is the effective actor: the badged person when a grant rode the
55
55
  // request, otherwise the authenticated principal. Attribution and write
56
56
  // scoping both derive from it, live, inside the escalation APIs.
57
- /**
58
- * Interpolates a step's params, or falls through when a `{claim.…}` or
59
- * `{item.…}` token has nothing to read: a literal token never reaches a row.
60
- */
61
- async function templated(step, ctx, render, item) {
62
- const tpl = await (0, context_1.stepTemplate)(step, ctx, item);
63
- try {
64
- return render(tpl);
65
- }
66
- catch (err) {
67
- if (err instanceof scanCodeService.ScanTemplateError)
68
- return null;
69
- throw err;
70
- }
71
- }
72
57
  async function claimStep(step, ctx) {
73
- const metadata = await templated(step, ctx, (tpl) => (0, context_1.interpolatedMetadata)(step, ctx, tpl));
58
+ const metadata = await (0, context_1.templated)(step, ctx, (tpl) => (0, context_1.interpolatedMetadata)(step, ctx, tpl));
74
59
  if (metadata === null)
75
60
  return null;
61
+ const notPrimed = await (0, grant_1.spendGrant)(ctx);
62
+ if (notPrimed)
63
+ return notPrimed;
76
64
  const result = await (0, metadata_1.claimByMetadata)({
77
65
  key: ctx.scheme.target_facet,
78
66
  value: ctx.parsed.target,
@@ -94,12 +82,15 @@ async function claimStep(step, ctx) {
94
82
  * choice passes the row it showed, so the resolve lands on that row or misses.
95
83
  */
96
84
  async function resolveStep(step, ctx, presentedId) {
97
- const rendered = await templated(step, ctx, (tpl) => ({
85
+ const rendered = await (0, context_1.templated)(step, ctx, (tpl) => ({
98
86
  resolverPayload: scanCodeService.interpolateScanTemplate(step.params?.resolverPayload ?? {}, tpl),
99
87
  metadata: (0, context_1.interpolatedMetadata)(step, ctx, tpl),
100
88
  }));
101
89
  if (rendered === null)
102
90
  return null;
91
+ const notPrimed = await (0, grant_1.spendGrant)(ctx);
92
+ if (notPrimed)
93
+ return notPrimed;
103
94
  const result = await (0, metadata_1.resolveByMetadata)({
104
95
  key: ctx.scheme.target_facet,
105
96
  value: ctx.parsed.target,
@@ -116,6 +107,8 @@ async function resolveStep(step, ctx, presentedId) {
116
107
  return (0, context_1.forbidden)(result.error);
117
108
  if (result.status === 409)
118
109
  return (0, context_1.conflict)(result.error);
110
+ if (result.status === 400 || result.status === 422)
111
+ return (0, context_1.refused)(result.error ?? 'the payload was not accepted');
119
112
  if (result.status !== 200)
120
113
  return result;
121
114
  const escalation = result.data.escalation
@@ -140,6 +133,9 @@ async function escalateStep(step, ctx) {
140
133
  if (cancelled.data?.outcome !== types_1.SCAN_OUTCOMES.EXECUTED)
141
134
  return cancelled;
142
135
  }
136
+ const notPrimed = await (0, grant_1.spendGrant)(ctx);
137
+ if (notPrimed)
138
+ return notPrimed;
143
139
  const created = await (0, create_1.createEscalation)({
144
140
  type: step.params?.escalationType ?? 'scan',
145
141
  role: step.params.targetRole,
@@ -173,6 +169,9 @@ async function releaseStep(step, ctx) {
173
169
  });
174
170
  if (escalations.length === 0)
175
171
  return null;
172
+ const notPrimed = await (0, grant_1.spendGrant)(ctx);
173
+ if (notPrimed)
174
+ return notPrimed;
176
175
  const result = await (0, claim_1.releaseEscalation)({ id: escalations[0].id }, ctx.auth);
177
176
  if (result.status === 403)
178
177
  return (0, context_1.forbidden)(result.error);
@@ -192,6 +191,8 @@ async function dispatchChoiceVerb(step, ctx, row) {
192
191
  switch (step.verb) {
193
192
  case types_1.SCAN_VERBS.SHOW_DETAIL:
194
193
  return (0, context_1.executed)(row, step); // already located under the actor's scope
194
+ case types_1.SCAN_VERBS.HOLD:
195
+ return (await (0, hold_1.holdStep)(step, ctx, row));
195
196
  case types_1.SCAN_VERBS.CLAIM:
196
197
  case types_1.SCAN_VERBS.CLAIM_SHOW_DETAIL:
197
198
  return (await claimStep(step, ctx)) ?? (await missReason(step, ctx, 'the item is no longer claimable'));
@@ -220,6 +221,9 @@ async function missReason(step, ctx, raceMessage) {
220
221
  async function cancelStep(step, ctx) {
221
222
  // Claim-as-lock: the atomic claim pins the row to this caller (or extends
222
223
  // their claim), serializing concurrent double-scans before the cancel.
224
+ const notPrimed = await (0, grant_1.spendGrant)(ctx);
225
+ if (notPrimed)
226
+ return notPrimed;
223
227
  const claimed = await (0, metadata_1.claimByMetadata)({
224
228
  key: ctx.scheme.target_facet,
225
229
  value: ctx.parsed.target,
@@ -237,98 +241,5 @@ async function cancelStep(step, ctx) {
237
241
  return (0, context_1.conflict)('Escalation is not cancellable (already terminal)');
238
242
  return (0, context_1.executed)(cancelled, step);
239
243
  }
240
- /**
241
- * Adds the scanned item to an accumulator. Two modes, one atomic write:
242
- *
243
- * - Item-locate (`params.accumulate.containerFacet`): the scan locates the
244
- * item's own pending row through the scheme facet, reads the container
245
- * facet value it carries, and adds the target to the container that shares
246
- * it, writing the item row as the reciprocal in the same statement. An
247
- * item with no row, or no container facet, falls through. An item whose
248
- * container has closed and whose successor has not parked yet answers
249
- * `no_open_container` with the item row, so the station can say "scan
250
- * again" instead of showing the bag with no hint.
251
- * - Container-locate (no `containerFacet`): the scan locates the container
252
- * by the scheme facet and adds `params.itemKey` (template).
253
- *
254
- * Templates may read `{claim.<facet>}` (the actor's live claim) and, in item
255
- * mode, `{item.<facet>}` (the located row); an unresolvable token falls
256
- * through. The write is the SDK's guarded statement; the locate only picks
257
- * ids. A container already holding the item answers conflict, never a
258
- * second add.
259
- */
260
- async function accumulateStep(step, ctx) {
261
- const options = step.params?.accumulate;
262
- let item;
263
- if (options?.containerFacet) {
264
- const located = await (0, locate_1.locateForStep)(step, ctx, 1);
265
- item = located?.escalations[0];
266
- if (!item)
267
- return null;
268
- }
269
- const rendered = await templated(step, ctx, (tpl) => ({
270
- payload: step.params?.resolverPayload
271
- ? scanCodeService.interpolateScanTemplate(step.params.resolverPayload, tpl)
272
- : undefined,
273
- metadata: { ...(0, context_1.interpolatedMetadata)(step, ctx, tpl), ...(0, context_1.provenance)(ctx) },
274
- itemKey: options?.containerFacet
275
- ? ctx.parsed.target
276
- : scanCodeService.interpolateScanTemplate(step.params.itemKey, tpl),
277
- }), item);
278
- if (rendered === null)
279
- return null;
280
- let request;
281
- let container;
282
- if (options?.containerFacet && item) {
283
- const containerValue = item.metadata?.[options.containerFacet];
284
- if (containerValue === undefined || containerValue === null || containerValue === '')
285
- return null;
286
- container = { facet: options.containerFacet, value: String(containerValue) };
287
- request = {
288
- key: container.facet,
289
- value: container.value,
290
- itemKey: rendered.itemKey,
291
- payload: rendered.payload,
292
- metadata: rendered.metadata,
293
- restrictRoles: options.container?.roles ?? options.containerRoles,
294
- container: options.container
295
- ? { types: options.container.types, subtypes: options.container.subtypes, facets: options.container.facets }
296
- : undefined,
297
- ...(options.reciprocal === false ? {} : { reciprocal: { id: item.id } }),
298
- };
299
- }
300
- else {
301
- request = {
302
- key: ctx.scheme.target_facet,
303
- value: ctx.parsed.target,
304
- itemKey: rendered.itemKey,
305
- payload: rendered.payload,
306
- metadata: rendered.metadata,
307
- restrictRoles: step.query?.roles,
308
- };
309
- }
310
- const result = await (0, accumulate_1.accumulateItemByMetadata)(request, ctx.auth);
311
- if (result.status === 404) {
312
- if (!container || !item)
313
- return null;
314
- return {
315
- status: 200,
316
- data: {
317
- outcome: types_1.SCAN_OUTCOMES.NO_OPEN_CONTAINER,
318
- verb: step.verb,
319
- escalation: item,
320
- container,
321
- fallback: ctx.rule.fallback,
322
- error: `No open container carries ${container.facet} = ${container.value}`,
323
- },
324
- };
325
- }
326
- if (result.status === 403)
327
- return (0, context_1.forbidden)(result.error);
328
- if (result.status === 409)
329
- return (0, context_1.conflict)(result.error);
330
- if (result.status !== 200)
331
- return result;
332
- const escalation = result.data.escalationId ? { id: result.data.escalationId, ...result.data } : undefined;
333
- return (0, context_1.executed)(escalation, step);
334
- }
244
+ var verb_accumulate_1 = require("./verb-accumulate");
245
+ Object.defineProperty(exports, "accumulateStep", { enumerable: true, get: function () { return verb_accumulate_1.accumulateStep; } });