@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
@@ -1,9 +1,6 @@
1
+ import { type ScanParseFailure } from '../../shared/scan-code';
1
2
  import { type ParsedScanCode, type ScanScheme } from '../../types';
2
- export interface ScanParseFailure {
3
- /** Why the code did not parse. */
4
- reason: 'empty' | 'unknown_version' | 'scheme_disabled' | 'malformed';
5
- detail: string;
6
- }
3
+ export type { ScanParseFailure };
7
4
  export type ScanParseResult = {
8
5
  ok: true;
9
6
  parsed: ParsedScanCode;
@@ -12,26 +9,26 @@ export type ScanParseResult = {
12
9
  ok: false;
13
10
  failure: ScanParseFailure;
14
11
  };
15
- /**
16
- * Parse a raw scan string against the configured schemes. Pure — no I/O.
17
- *
18
- * The leading TWO digits pick the scheme (10-99, so a code never starts with a
19
- * leading zero); the scheme then defines how the remainder splits into a
20
- * single-digit category (0-9) and the target:
21
- * - delimited: `10:1:ABC-123` (delimiter from the scheme row)
22
- * - fixed: `1017554332` (one category digit, then target_length digits)
23
- */
12
+ /** Parse a raw scan string against the configured schemes. Pure; see shared/scan-code. */
24
13
  export declare function parseScanCode(raw: string, schemes: ScanScheme[]): ScanParseResult;
25
14
  export interface ScanTemplateContext {
26
15
  target: string;
27
16
  category: string;
28
17
  scannedAt: string;
18
+ /** The code as scanned; defaults to the target. */
19
+ code?: string;
29
20
  /** The acting user's single live claim, its metadata; absent when none or ambiguous. */
30
21
  claim?: Record<string, unknown>;
31
- /** The row an item-mode accumulate step located, its metadata. */
22
+ /** The row the step located (item-mode accumulate, hold), its metadata. */
32
23
  item?: Record<string, unknown>;
24
+ /** The held subject's row: its metadata plus `id`. */
25
+ subject?: Record<string, unknown>;
26
+ /** The container a subject step located, its metadata. */
27
+ container?: Record<string, unknown>;
28
+ /** The batch a fill step read: `pending`, `total`, `filled`. */
29
+ fill?: Record<string, unknown>;
33
30
  }
34
- /** A `{claim.x}` or `{item.x}` token the context cannot resolve. */
31
+ /** A bag token the context cannot resolve. */
35
32
  export declare class ScanTemplateError extends Error {
36
33
  readonly token: string;
37
34
  readonly reason: string;
@@ -41,9 +38,15 @@ export declare class ScanTemplateError extends Error {
41
38
  export declare function mentionsClaimToken(value: unknown): boolean;
42
39
  /**
43
40
  * Replace the template tokens inside string values of a params object.
44
- * Deep, pure, non-mutating. The three scan tokens are plain text
45
- * replacement; `{claim.<facet>}` and `{item.<facet>}` read the context's
46
- * facet bags and throw {@link ScanTemplateError} when they cannot resolve,
47
- * so a literal token never reaches a row. No expression language.
41
+ * Deep, pure, non-mutating. The scan tokens are plain text replacement; the
42
+ * bag tokens (`{claim.x}`, `{item.x}`, `{subject.x}`, `{container.x}`,
43
+ * `{fill.x}`) read the context's facet bags and throw
44
+ * {@link ScanTemplateError} when they cannot resolve, so a literal token
45
+ * never reaches a row. No expression language.
48
46
  */
49
47
  export declare function interpolateScanTemplate<T>(value: T, ctx: ScanTemplateContext): T;
48
+ /**
49
+ * Render refusal copy, degrading instead of failing: a token with nothing to
50
+ * read becomes an empty string, so a refusal always has words to show.
51
+ */
52
+ export declare function renderScanCopy(markdown: string, ctx: ScanTemplateContext): string;
@@ -4,87 +4,14 @@ exports.ScanTemplateError = void 0;
4
4
  exports.parseScanCode = parseScanCode;
5
5
  exports.mentionsClaimToken = mentionsClaimToken;
6
6
  exports.interpolateScanTemplate = interpolateScanTemplate;
7
+ exports.renderScanCopy = renderScanCopy;
8
+ const scan_code_1 = require("../../shared/scan-code");
7
9
  const types_1 = require("../../types");
8
- /**
9
- * Parse a raw scan string against the configured schemes. Pure — no I/O.
10
- *
11
- * The leading TWO digits pick the scheme (10-99, so a code never starts with a
12
- * leading zero); the scheme then defines how the remainder splits into a
13
- * single-digit category (0-9) and the target:
14
- * - delimited: `10:1:ABC-123` (delimiter from the scheme row)
15
- * - fixed: `1017554332` (one category digit, then target_length digits)
16
- */
10
+ /** Parse a raw scan string against the configured schemes. Pure; see shared/scan-code. */
17
11
  function parseScanCode(raw, schemes) {
18
- const code = raw.trim();
19
- if (!code) {
20
- return { ok: false, failure: { reason: 'empty', detail: 'empty scan code' } };
21
- }
22
- const versionToken = code.slice(0, 2);
23
- const version = Number(versionToken);
24
- if (!/^[0-9]{2}$/.test(versionToken) || version < 10 || version > 99) {
25
- return {
26
- ok: false,
27
- failure: { reason: 'unknown_version', detail: `code must start with a two-digit scheme 10-99, got "${versionToken}"` },
28
- };
29
- }
30
- const scheme = schemes.find((s) => s.version === version);
31
- if (!scheme) {
32
- return {
33
- ok: false,
34
- failure: { reason: 'unknown_version', detail: `no scan scheme configured for version ${version}` },
35
- };
36
- }
37
- if (!scheme.enabled) {
38
- return {
39
- ok: false,
40
- failure: { reason: 'scheme_disabled', detail: `scan scheme ${version} ("${scheme.name}") is disabled` },
41
- };
42
- }
43
- if (scheme.encoding === types_1.SCAN_ENCODINGS.DELIMITED) {
44
- return parseDelimited(code, version, scheme);
45
- }
46
- return parseFixed(code, version, scheme);
12
+ return (0, scan_code_1.parseScanCode)(raw, schemes);
47
13
  }
48
- function parseDelimited(code, version, scheme) {
49
- const d = scheme.delimiter;
50
- // version(2 digits) <d> category(1 digit) <d> target(rest, non-empty)
51
- if (code[2] !== d) {
52
- return malformed(scheme, `expected "${d}" after the two-digit scheme`);
53
- }
54
- const category = code.slice(3, 4);
55
- if (!/^[0-9]$/.test(category)) {
56
- return malformed(scheme, 'category must be a single digit');
57
- }
58
- if (code[4] !== d) {
59
- return malformed(scheme, `expected "${d}" after the category`);
60
- }
61
- const target = code.slice(5);
62
- if (!target) {
63
- return malformed(scheme, 'target is empty');
64
- }
65
- return { ok: true, parsed: { version, category, target }, scheme };
66
- }
67
- function parseFixed(code, version, scheme) {
68
- const targetLength = scheme.target_length ?? 0;
69
- const expected = 2 + 1 + targetLength;
70
- // UPC-A wedges deliver the trailing check digit too; accept it as slack.
71
- if (!/^[0-9]+$/.test(code)) {
72
- return malformed(scheme, 'fixed encoding accepts digits only');
73
- }
74
- if (code.length !== expected && code.length !== expected + 1) {
75
- return malformed(scheme, `expected ${expected} digits (or ${expected + 1} with check digit), got ${code.length}`);
76
- }
77
- const category = code.slice(2, 3);
78
- const target = code.slice(3, 3 + targetLength);
79
- return { ok: true, parsed: { version, category, target }, scheme };
80
- }
81
- function malformed(scheme, detail) {
82
- return {
83
- ok: false,
84
- failure: { reason: 'malformed', detail: `scheme ${scheme.version} ("${scheme.name}"): ${detail}` },
85
- };
86
- }
87
- /** A `{claim.x}` or `{item.x}` token the context cannot resolve. */
14
+ /** A bag token the context cannot resolve. */
88
15
  class ScanTemplateError extends Error {
89
16
  constructor(token, reason) {
90
17
  super(`scan template ${token}: ${reason}`);
@@ -94,37 +21,45 @@ class ScanTemplateError extends Error {
94
21
  }
95
22
  }
96
23
  exports.ScanTemplateError = ScanTemplateError;
97
- const BAG_TOKEN = /\{(claim|item)\.([a-zA-Z0-9_]+)\}/g;
24
+ const BAG_TOKEN = /\{(claim|item|subject|container|fill)\.([a-zA-Z0-9_]+)\}/g;
25
+ const MISSING_BAG = {
26
+ claim: 'the actor holds no single live claim',
27
+ item: 'no located item row on this step',
28
+ subject: 'no subject is held',
29
+ container: 'no container was located',
30
+ fill: 'no batch was read',
31
+ };
98
32
  /** True when any string in the params mentions a `{claim.…}` token. */
99
33
  function mentionsClaimToken(value) {
100
34
  return JSON.stringify(value ?? null).includes(`{${types_1.SCAN_TEMPLATE_BAGS.CLAIM}.`);
101
35
  }
102
36
  function resolveBagToken(ctx, bag, facet, token) {
103
- const source = bag === types_1.SCAN_TEMPLATE_BAGS.CLAIM ? ctx.claim : ctx.item;
104
- if (!source) {
105
- throw new ScanTemplateError(token, bag === types_1.SCAN_TEMPLATE_BAGS.CLAIM
106
- ? 'the actor holds no single live claim'
107
- : 'no located item row on this step');
108
- }
37
+ const source = ctx[bag];
38
+ if (!source)
39
+ throw new ScanTemplateError(token, MISSING_BAG[bag]);
109
40
  const v = source[facet];
110
41
  if (v === undefined || v === null || v === '') {
111
42
  throw new ScanTemplateError(token, `facet ${facet} is absent`);
112
43
  }
44
+ if (Array.isArray(v))
45
+ return v.join(', ');
113
46
  return typeof v === 'object' ? JSON.stringify(v) : String(v);
114
47
  }
115
48
  /**
116
49
  * Replace the template tokens inside string values of a params object.
117
- * Deep, pure, non-mutating. The three scan tokens are plain text
118
- * replacement; `{claim.<facet>}` and `{item.<facet>}` read the context's
119
- * facet bags and throw {@link ScanTemplateError} when they cannot resolve,
120
- * so a literal token never reaches a row. No expression language.
50
+ * Deep, pure, non-mutating. The scan tokens are plain text replacement; the
51
+ * bag tokens (`{claim.x}`, `{item.x}`, `{subject.x}`, `{container.x}`,
52
+ * `{fill.x}`) read the context's facet bags and throw
53
+ * {@link ScanTemplateError} when they cannot resolve, so a literal token
54
+ * never reaches a row. No expression language.
121
55
  */
122
56
  function interpolateScanTemplate(value, ctx) {
123
57
  if (typeof value === 'string') {
124
58
  const scanned = value
125
59
  .split(types_1.SCAN_TEMPLATE_TOKENS.TARGET).join(ctx.target)
126
60
  .split(types_1.SCAN_TEMPLATE_TOKENS.CATEGORY).join(ctx.category)
127
- .split(types_1.SCAN_TEMPLATE_TOKENS.SCANNED_AT).join(ctx.scannedAt);
61
+ .split(types_1.SCAN_TEMPLATE_TOKENS.SCANNED_AT).join(ctx.scannedAt)
62
+ .split(types_1.SCAN_TEMPLATE_TOKENS.CODE).join(ctx.code ?? ctx.target);
128
63
  return scanned.replace(BAG_TOKEN, (token, bag, facet) => resolveBagToken(ctx, bag, facet, token));
129
64
  }
130
65
  if (Array.isArray(value)) {
@@ -139,3 +74,23 @@ function interpolateScanTemplate(value, ctx) {
139
74
  }
140
75
  return value;
141
76
  }
77
+ /**
78
+ * Render refusal copy, degrading instead of failing: a token with nothing to
79
+ * read becomes an empty string, so a refusal always has words to show.
80
+ */
81
+ function renderScanCopy(markdown, ctx) {
82
+ try {
83
+ return interpolateScanTemplate(markdown, ctx);
84
+ }
85
+ catch {
86
+ const safe = markdown.replace(BAG_TOKEN, (token, bag, facet) => {
87
+ try {
88
+ return resolveBagToken(ctx, bag, facet, token);
89
+ }
90
+ catch {
91
+ return '';
92
+ }
93
+ });
94
+ return interpolateScanTemplate(safe, ctx);
95
+ }
96
+ }
@@ -18,6 +18,7 @@ function mapScheme(row) {
18
18
  kind: row.kind ?? 'action',
19
19
  grant_ttl_seconds: row.grant_ttl_seconds ?? null,
20
20
  grant_max_uses: row.grant_max_uses ?? 0,
21
+ grant_scope: row.grant_scope ?? 'action',
21
22
  enabled: row.enabled,
22
23
  created_at: row.created_at,
23
24
  updated_at: row.updated_at,
@@ -2,16 +2,16 @@ export declare const LIST_SCHEMES = "SELECT * FROM lt_config_scan_schemes ORDER
2
2
  export declare const GET_SCHEME = "SELECT * FROM lt_config_scan_schemes WHERE version = $1";
3
3
  export declare const LIST_ACTIONS = "SELECT * FROM lt_config_scan_actions WHERE scheme_version = $1 ORDER BY category";
4
4
  export declare const GET_ACTION = "SELECT * FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2";
5
- export declare const UPSERT_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n kind = EXCLUDED.kind,\n grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,\n grant_max_uses = EXCLUDED.grant_max_uses,\n enabled = EXCLUDED.enabled\nRETURNING *";
5
+ export declare const UPSERT_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled, grant_scope)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n kind = EXCLUDED.kind,\n grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,\n grant_max_uses = EXCLUDED.grant_max_uses,\n grant_scope = EXCLUDED.grant_scope,\n enabled = EXCLUDED.enabled\nRETURNING *";
6
6
  export declare const DELETE_SCHEME = "DELETE FROM lt_config_scan_schemes WHERE version = $1";
7
7
  export declare const UPSERT_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO UPDATE SET\n name = EXCLUDED.name,\n steps = EXCLUDED.steps,\n fallback = EXCLUDED.fallback,\n not_primed = EXCLUDED.not_primed,\n enabled = EXCLUDED.enabled\nRETURNING *";
8
8
  export declare const DELETE_ACTION = "DELETE FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2";
9
- export declare const SEED_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO NOTHING";
9
+ export declare const SEED_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled, grant_scope)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\nON CONFLICT (version) DO NOTHING";
10
10
  export declare const SEED_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO NOTHING";
11
11
  /**
12
12
  * Apply — same column set as the upsert, guarded by IS DISTINCT FROM so an
13
13
  * unchanged declaration is a zero-row no-op. `(xmax = 0)` distinguishes
14
14
  * insert from update. jsonb columns compare content-wise in SQL.
15
15
  */
16
- export declare const APPLY_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n kind = EXCLUDED.kind,\n grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,\n grant_max_uses = EXCLUDED.grant_max_uses,\n enabled = EXCLUDED.enabled,\n updated_at = NOW()\nWHERE (lt_config_scan_schemes.name, lt_config_scan_schemes.description,\n lt_config_scan_schemes.target_facet, lt_config_scan_schemes.encoding,\n lt_config_scan_schemes.delimiter, lt_config_scan_schemes.target_length,\n lt_config_scan_schemes.kind, lt_config_scan_schemes.grant_ttl_seconds,\n lt_config_scan_schemes.grant_max_uses, lt_config_scan_schemes.enabled)\n IS DISTINCT FROM\n (EXCLUDED.name, EXCLUDED.description, EXCLUDED.target_facet,\n EXCLUDED.encoding, EXCLUDED.delimiter, EXCLUDED.target_length,\n EXCLUDED.kind, EXCLUDED.grant_ttl_seconds, EXCLUDED.grant_max_uses,\n EXCLUDED.enabled)\nRETURNING (xmax = 0) AS inserted";
16
+ export declare const APPLY_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled, grant_scope)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n kind = EXCLUDED.kind,\n grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,\n grant_max_uses = EXCLUDED.grant_max_uses,\n grant_scope = EXCLUDED.grant_scope,\n enabled = EXCLUDED.enabled,\n updated_at = NOW()\nWHERE (lt_config_scan_schemes.name, lt_config_scan_schemes.description,\n lt_config_scan_schemes.target_facet, lt_config_scan_schemes.encoding,\n lt_config_scan_schemes.delimiter, lt_config_scan_schemes.target_length,\n lt_config_scan_schemes.kind, lt_config_scan_schemes.grant_ttl_seconds,\n lt_config_scan_schemes.grant_max_uses, lt_config_scan_schemes.enabled,\n lt_config_scan_schemes.grant_scope)\n IS DISTINCT FROM\n (EXCLUDED.name, EXCLUDED.description, EXCLUDED.target_facet,\n EXCLUDED.encoding, EXCLUDED.delimiter, EXCLUDED.target_length,\n EXCLUDED.kind, EXCLUDED.grant_ttl_seconds, EXCLUDED.grant_max_uses,\n EXCLUDED.enabled, EXCLUDED.grant_scope)\nRETURNING (xmax = 0) AS inserted";
17
17
  export declare const APPLY_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO UPDATE SET\n name = EXCLUDED.name,\n steps = EXCLUDED.steps,\n fallback = EXCLUDED.fallback,\n not_primed = EXCLUDED.not_primed,\n enabled = EXCLUDED.enabled,\n updated_at = NOW()\nWHERE (lt_config_scan_actions.name, lt_config_scan_actions.steps,\n lt_config_scan_actions.fallback, lt_config_scan_actions.not_primed,\n lt_config_scan_actions.enabled)\n IS DISTINCT FROM\n (EXCLUDED.name, EXCLUDED.steps, EXCLUDED.fallback,\n EXCLUDED.not_primed, EXCLUDED.enabled)\nRETURNING (xmax = 0) AS inserted";
@@ -18,8 +18,8 @@ SELECT * FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2
18
18
  exports.UPSERT_SCHEME = `\
19
19
  INSERT INTO lt_config_scan_schemes
20
20
  (version, name, description, target_facet, encoding, delimiter, target_length,
21
- kind, grant_ttl_seconds, grant_max_uses, enabled)
22
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
21
+ kind, grant_ttl_seconds, grant_max_uses, enabled, grant_scope)
22
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
23
23
  ON CONFLICT (version) DO UPDATE SET
24
24
  name = EXCLUDED.name,
25
25
  description = EXCLUDED.description,
@@ -30,6 +30,7 @@ ON CONFLICT (version) DO UPDATE SET
30
30
  kind = EXCLUDED.kind,
31
31
  grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,
32
32
  grant_max_uses = EXCLUDED.grant_max_uses,
33
+ grant_scope = EXCLUDED.grant_scope,
33
34
  enabled = EXCLUDED.enabled
34
35
  RETURNING *`;
35
36
  exports.DELETE_SCHEME = `\
@@ -53,8 +54,8 @@ DELETE FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2`;
53
54
  exports.SEED_SCHEME = `\
54
55
  INSERT INTO lt_config_scan_schemes
55
56
  (version, name, description, target_facet, encoding, delimiter, target_length,
56
- kind, grant_ttl_seconds, grant_max_uses, enabled)
57
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
57
+ kind, grant_ttl_seconds, grant_max_uses, enabled, grant_scope)
58
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
58
59
  ON CONFLICT (version) DO NOTHING`;
59
60
  exports.SEED_ACTION = `\
60
61
  INSERT INTO lt_config_scan_actions
@@ -72,8 +73,8 @@ ON CONFLICT (scheme_version, category) DO NOTHING`;
72
73
  exports.APPLY_SCHEME = `\
73
74
  INSERT INTO lt_config_scan_schemes
74
75
  (version, name, description, target_facet, encoding, delimiter, target_length,
75
- kind, grant_ttl_seconds, grant_max_uses, enabled)
76
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
76
+ kind, grant_ttl_seconds, grant_max_uses, enabled, grant_scope)
77
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
77
78
  ON CONFLICT (version) DO UPDATE SET
78
79
  name = EXCLUDED.name,
79
80
  description = EXCLUDED.description,
@@ -84,18 +85,20 @@ ON CONFLICT (version) DO UPDATE SET
84
85
  kind = EXCLUDED.kind,
85
86
  grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,
86
87
  grant_max_uses = EXCLUDED.grant_max_uses,
88
+ grant_scope = EXCLUDED.grant_scope,
87
89
  enabled = EXCLUDED.enabled,
88
90
  updated_at = NOW()
89
91
  WHERE (lt_config_scan_schemes.name, lt_config_scan_schemes.description,
90
92
  lt_config_scan_schemes.target_facet, lt_config_scan_schemes.encoding,
91
93
  lt_config_scan_schemes.delimiter, lt_config_scan_schemes.target_length,
92
94
  lt_config_scan_schemes.kind, lt_config_scan_schemes.grant_ttl_seconds,
93
- lt_config_scan_schemes.grant_max_uses, lt_config_scan_schemes.enabled)
95
+ lt_config_scan_schemes.grant_max_uses, lt_config_scan_schemes.enabled,
96
+ lt_config_scan_schemes.grant_scope)
94
97
  IS DISTINCT FROM
95
98
  (EXCLUDED.name, EXCLUDED.description, EXCLUDED.target_facet,
96
99
  EXCLUDED.encoding, EXCLUDED.delimiter, EXCLUDED.target_length,
97
100
  EXCLUDED.kind, EXCLUDED.grant_ttl_seconds, EXCLUDED.grant_max_uses,
98
- EXCLUDED.enabled)
101
+ EXCLUDED.enabled, EXCLUDED.grant_scope)
99
102
  RETURNING (xmax = 0) AS inserted`;
100
103
  exports.APPLY_ACTION = `\
101
104
  INSERT INTO lt_config_scan_actions
@@ -0,0 +1,7 @@
1
+ import { type ScanStep } from '../../types';
2
+ /**
3
+ * Hold, fill, and the subject vocabulary (subject gate, match, refuse,
4
+ * accumulate from/into). A step that can never find its subject, or a
5
+ * guard that can never pass, fails the upsert rather than the bench.
6
+ */
7
+ export declare function assertValidSubjectStep(step: ScanStep, at: string): void;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertValidSubjectStep = assertValidSubjectStep;
4
+ const types_1 = require("../../types");
5
+ const facet_sql_1 = require("../escalation/facet-sql");
6
+ function isSchemeList(value) {
7
+ return Array.isArray(value) && value.length > 0
8
+ && value.every((v) => Number.isInteger(v) && v >= 10 && v <= 99);
9
+ }
10
+ function isStringList(value) {
11
+ return Array.isArray(value) && value.length > 0 && value.every((v) => typeof v === 'string' && v);
12
+ }
13
+ function isPlainObject(value) {
14
+ return !!value && typeof value === 'object' && !Array.isArray(value);
15
+ }
16
+ /**
17
+ * Hold, fill, and the subject vocabulary (subject gate, match, refuse,
18
+ * accumulate from/into). A step that can never find its subject, or a
19
+ * guard that can never pass, fails the upsert rather than the bench.
20
+ */
21
+ function assertValidSubjectStep(step, at) {
22
+ const accumulate = step.params?.accumulate;
23
+ const subjectMode = accumulate?.from === 'subject' || accumulate?.into === 'subject'
24
+ || (step.verb === types_1.SCAN_VERBS.FILL && step.params?.fill?.into === 'subject');
25
+ if (step.subject !== undefined) {
26
+ if (!isPlainObject(step.subject) || !isSchemeList(step.subject.schemes)) {
27
+ throw new Error(`${at}: subject.schemes must be a non-empty array of scheme versions (10-99)`);
28
+ }
29
+ if (step.subject.claimedByOther !== undefined
30
+ && step.subject.claimedByOther !== 'refuse' && step.subject.claimedByOther !== 'allow') {
31
+ throw new Error(`${at}: subject.claimedByOther must be 'refuse' or 'allow'`);
32
+ }
33
+ const facets = step.subject.facets;
34
+ if (facets !== undefined) {
35
+ if (!facets || typeof facets !== 'object' || Array.isArray(facets) || Object.keys(facets).length === 0) {
36
+ throw new Error(`${at}: subject.facets must be a non-empty object`);
37
+ }
38
+ for (const [key, value] of Object.entries(facets)) {
39
+ if (!facet_sql_1.FACET_KEY.test(key))
40
+ throw new Error(`${at}: subject.facets key "${key}" must be a facet key`);
41
+ if (!['string', 'number', 'boolean'].includes(typeof value)) {
42
+ throw new Error(`${at}: subject.facets.${key} must be a string, number, or boolean`);
43
+ }
44
+ }
45
+ }
46
+ if (step.verb !== types_1.SCAN_VERBS.ACCUMULATE && step.verb !== types_1.SCAN_VERBS.FILL) {
47
+ throw new Error(`${at}: a subject gate applies only to accumulate and fill steps`);
48
+ }
49
+ if (step.confirm)
50
+ throw new Error(`${at}: a subject step acts on the scan; it cannot carry confirm`);
51
+ if (!subjectMode) {
52
+ throw new Error(`${at}: a subject step must act on it (accumulate from/into 'subject', or fill into 'subject')`);
53
+ }
54
+ }
55
+ else if (subjectMode) {
56
+ throw new Error(`${at}: acting on the held subject requires a subject gate`);
57
+ }
58
+ if (accumulate?.from !== undefined && accumulate.from !== 'subject') {
59
+ throw new Error(`${at}: params.accumulate.from must be 'subject'`);
60
+ }
61
+ if (accumulate?.into !== undefined && accumulate.into !== 'subject') {
62
+ throw new Error(`${at}: params.accumulate.into must be 'subject'`);
63
+ }
64
+ if (accumulate?.from && accumulate.into) {
65
+ throw new Error(`${at}: params.accumulate.from and into are exclusive`);
66
+ }
67
+ if ((accumulate?.from || accumulate?.into) && accumulate.containerFacet) {
68
+ throw new Error(`${at}: params.accumulate.containerFacet is item mode; drop it for from/into 'subject'`);
69
+ }
70
+ if (accumulate?.from && !step.params?.itemKey) {
71
+ throw new Error(`${at}: from-subject accumulate requires params.itemKey (e.g. '{subject.<facet>}')`);
72
+ }
73
+ if (step.match !== undefined) {
74
+ if (!step.subject)
75
+ throw new Error(`${at}: match applies only to steps with a subject gate`);
76
+ if (!isPlainObject(step.match))
77
+ throw new Error(`${at}: match must be an object`);
78
+ if (step.match.target === undefined && step.match.facets === undefined) {
79
+ throw new Error(`${at}: match needs target or facets`);
80
+ }
81
+ if (step.match.target !== undefined && !isStringList(step.match.target)) {
82
+ throw new Error(`${at}: match.target must be a non-empty array of templates`);
83
+ }
84
+ if (step.match.facets !== undefined) {
85
+ if (!isStringList(step.match.facets) || !step.match.facets.every((f) => facet_sql_1.FACET_KEY.test(f))) {
86
+ throw new Error(`${at}: match.facets must be a non-empty array of facet keys`);
87
+ }
88
+ if (accumulate?.from !== 'subject') {
89
+ throw new Error(`${at}: match.facets compares the located container, which only a from-subject accumulate has`);
90
+ }
91
+ }
92
+ }
93
+ if (step.refuse !== undefined) {
94
+ if (!isPlainObject(step.refuse) || typeof step.refuse.markdown !== 'string' || !step.refuse.markdown) {
95
+ throw new Error(`${at}: refuse.markdown is required`);
96
+ }
97
+ if (step.refuse.conflict !== undefined && typeof step.refuse.conflict !== 'string') {
98
+ throw new Error(`${at}: refuse.conflict must be markdown`);
99
+ }
100
+ if (step.refuse.missing !== undefined) {
101
+ if (typeof step.refuse.missing !== 'string' || !step.refuse.missing) {
102
+ throw new Error(`${at}: refuse.missing must be markdown`);
103
+ }
104
+ if (accumulate?.from !== 'subject') {
105
+ throw new Error(`${at}: refuse.missing applies only to a from-subject accumulate`);
106
+ }
107
+ }
108
+ }
109
+ if (step.verb === types_1.SCAN_VERBS.HOLD)
110
+ assertValidHold(step, at);
111
+ else if (step.params?.hold !== undefined)
112
+ throw new Error(`${at}: params.hold applies only to hold steps`);
113
+ if (step.verb === types_1.SCAN_VERBS.FILL)
114
+ assertValidFill(step, at);
115
+ else if (step.params?.fill !== undefined)
116
+ throw new Error(`${at}: params.fill applies only to fill steps`);
117
+ }
118
+ function assertValidHold(step, at) {
119
+ if (step.cardinality === 'many')
120
+ throw new Error(`${at}: hold locates a single row (cardinality first)`);
121
+ const hold = step.params?.hold;
122
+ if (hold === undefined)
123
+ return;
124
+ if (!isPlainObject(hold))
125
+ throw new Error(`${at}: params.hold must be an object`);
126
+ if (hold.ttlSeconds !== undefined && (!Number.isInteger(hold.ttlSeconds)
127
+ || hold.ttlSeconds < types_1.SCAN_HOLD_TTL_MIN_SECONDS || hold.ttlSeconds > types_1.SCAN_HOLD_TTL_MAX_SECONDS)) {
128
+ throw new Error(`${at}: params.hold.ttlSeconds must be ${types_1.SCAN_HOLD_TTL_MIN_SECONDS}-${types_1.SCAN_HOLD_TTL_MAX_SECONDS}`);
129
+ }
130
+ if (hold.label !== undefined && typeof hold.label !== 'string') {
131
+ throw new Error(`${at}: params.hold.label must be a template string`);
132
+ }
133
+ if (hold.expect !== undefined) {
134
+ if (!isPlainObject(hold.expect) || !isSchemeList(hold.expect.schemes)) {
135
+ throw new Error(`${at}: params.hold.expect.schemes must be a non-empty array of scheme versions`);
136
+ }
137
+ if (hold.expect.prompt !== undefined && typeof hold.expect.prompt !== 'string') {
138
+ throw new Error(`${at}: params.hold.expect.prompt must be markdown`);
139
+ }
140
+ }
141
+ }
142
+ function assertValidFill(step, at) {
143
+ const fill = step.params?.fill;
144
+ if (!fill || !isPlainObject(fill))
145
+ throw new Error(`${at}: fill requires params.fill`);
146
+ if (fill.into !== 'subject' && fill.into !== 'scanned') {
147
+ throw new Error(`${at}: params.fill.into must be 'subject' or 'scanned'`);
148
+ }
149
+ const separator = fill.separator ?? types_1.SCAN_FILL_SEPARATOR_DEFAULT;
150
+ if (typeof separator !== 'string' || separator.length !== 1) {
151
+ throw new Error(`${at}: params.fill.separator must be one character`);
152
+ }
153
+ if (fill.payload !== undefined && !isPlainObject(fill.payload)) {
154
+ throw new Error(`${at}: params.fill.payload must be an object`);
155
+ }
156
+ if (step.confirm)
157
+ throw new Error(`${at}: fill cannot carry confirm`);
158
+ }
@@ -5,6 +5,13 @@ import { type ScanScheme, type ScanStep } from '../../types';
5
5
  * than a loud upsert failure.
6
6
  */
7
7
  export declare function assertValidScheme(scheme: Partial<ScanScheme>): void;
8
+ /**
9
+ * A scheme must read codes no other scheme reads. Delimited and fixed
10
+ * schemes are told apart by their version prefix; a gtin scheme has none,
11
+ * so there is at most one, and no enabled fixed scheme may accept a GTIN
12
+ * length while it is enabled. Throws naming both schemes.
13
+ */
14
+ export declare function assertSchemesCoexist(candidate: Partial<ScanScheme>, existing: ScanScheme[]): void;
8
15
  /** Identity rules never walk steps — their fallback is the unknown-badge screen. */
9
16
  export declare function assertValidIdentityRule(steps: ScanStep[]): void;
10
17
  /**