@hotmeshio/long-tail 0.10.13 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -4
- package/build/api/escalations/analytics.d.ts +6 -0
- package/build/api/escalations/analytics.js +123 -0
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +4 -1
- package/build/api/escalations/metadata.js +1 -1
- package/build/api/escalations/resolve.js +4 -4
- package/build/api/roles.d.ts +4 -0
- package/build/api/roles.js +8 -0
- package/build/api/scan-codes/choice.d.ts +11 -0
- package/build/api/scan-codes/choice.js +136 -0
- package/build/api/scan-codes/context.d.ts +24 -0
- package/build/api/scan-codes/context.js +86 -0
- package/build/api/scan-codes/execute.d.ts +1 -0
- package/build/api/scan-codes/execute.js +49 -244
- package/build/api/scan-codes/identity.d.ts +18 -0
- package/build/api/scan-codes/identity.js +116 -0
- package/build/api/scan-codes/index.d.ts +2 -0
- package/build/api/scan-codes/index.js +6 -1
- package/build/api/scan-codes/locate.d.ts +14 -0
- package/build/api/scan-codes/locate.js +127 -0
- package/build/api/scan-codes/present.d.ts +9 -0
- package/build/api/scan-codes/present.js +59 -0
- package/build/api/scan-codes/verbs.d.ts +15 -0
- package/build/api/scan-codes/verbs.js +205 -0
- package/build/bin/ltc.js +33 -0
- package/build/lib/cli/commands/escalations.d.ts +31 -0
- package/build/lib/cli/commands/escalations.js +88 -0
- package/build/lib/db/schemas/028_role_entity_facet.sql +18 -0
- package/build/lib/db/schemas/029_scan_scheme_kind.sql +31 -0
- package/build/modules/config.d.ts +5 -0
- package/build/modules/config.js +12 -0
- package/build/routes/escalations/acting.d.ts +12 -0
- package/build/routes/escalations/acting.js +25 -0
- package/build/routes/escalations/analytics.d.ts +8 -0
- package/build/routes/escalations/analytics.js +63 -0
- package/build/routes/escalations/index.js +3 -0
- package/build/routes/escalations/resolve.js +8 -1
- package/build/routes/escalations/single.js +13 -4
- package/build/routes/roles.js +1 -1
- package/build/routes/scan-codes.js +28 -2
- package/build/scripts/ortho-populate.js +14 -0
- package/build/scripts/printer-cycle.d.ts +25 -0
- package/build/scripts/printer-cycle.js +169 -0
- package/build/scripts/twin-farm.js +19 -5
- package/build/sdk/index.d.ts +2 -0
- package/build/sdk/index.js +3 -0
- package/build/services/escalation/aggregate-sql.d.ts +36 -0
- package/build/services/escalation/aggregate-sql.js +253 -0
- package/build/services/escalation/aggregate-validate.d.ts +57 -0
- package/build/services/escalation/aggregate-validate.js +218 -0
- package/build/services/escalation/aggregates.d.ts +26 -0
- package/build/services/escalation/aggregates.js +204 -0
- package/build/services/escalation/client.js +57 -21
- package/build/services/escalation/facet-sql.js +17 -0
- package/build/services/escalation/index.d.ts +2 -0
- package/build/services/escalation/index.js +8 -1
- package/build/services/escalation/metrics-cache.d.ts +18 -0
- package/build/services/escalation/metrics-cache.js +47 -1
- package/build/services/escalation/queries.js +2 -0
- package/build/services/escalation/resolver-validation.d.ts +1 -1
- package/build/services/escalation/resolver-validation.js +12 -5
- package/build/services/escalation/submit-guard.d.ts +29 -0
- package/build/services/escalation/submit-guard.js +57 -0
- package/build/services/iam/acting-identity.d.ts +16 -0
- package/build/services/iam/acting-identity.js +60 -0
- package/build/services/role/index.js +2 -0
- package/build/services/role/sql.d.ts +10 -2
- package/build/services/role/sql.js +14 -1
- package/build/services/role/types.d.ts +16 -0
- package/build/services/scan-code/read.js +4 -0
- package/build/services/scan-code/sql.d.ts +4 -4
- package/build/services/scan-code/sql.js +14 -8
- package/build/services/scan-code/validate.d.ts +2 -0
- package/build/services/scan-code/validate.js +86 -0
- package/build/services/scan-code/write.d.ts +4 -0
- package/build/services/scan-code/write.js +16 -2
- package/build/services/user/crud.d.ts +6 -0
- package/build/services/user/crud.js +16 -0
- package/build/services/user/index.d.ts +1 -1
- package/build/services/user/index.js +2 -1
- package/build/services/user/sql.d.ts +8 -0
- package/build/services/user/sql.js +9 -1
- package/build/shared/form-validation/index.d.ts +4 -0
- package/build/shared/form-validation/index.js +4 -0
- package/build/shared/form-validation/x-lt-labels.d.ts +28 -0
- package/build/shared/form-validation/x-lt-labels.js +42 -0
- package/build/shared/form-validation/x-lt-query.d.ts +56 -0
- package/build/shared/form-validation/x-lt-query.js +49 -0
- package/build/shared/form-validation/x-lt-submit-guard.d.ts +46 -0
- package/build/shared/form-validation/x-lt-submit-guard.js +25 -0
- package/build/shared/form-validation/x-lt-submit-on-claim.d.ts +22 -0
- package/build/shared/form-validation/x-lt-submit-on-claim.js +28 -0
- package/build/system/mcp-servers/admin/escalations.js +34 -0
- package/build/system/mcp-servers/admin/scan-codes.js +17 -1
- package/build/system/mcp-servers/admin/schemas.d.ts +643 -25
- package/build/system/mcp-servers/admin/schemas.js +127 -19
- package/build/system/mcp-servers/admin/users.js +3 -1
- package/build/system/mcp-servers/human-queue-schemas.d.ts +2 -2
- package/build/system/seed/tool-manifests-admin.d.ts +2283 -0
- package/build/system/seed/tool-manifests-admin.js +8 -5
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/analytics.d.ts +154 -0
- package/build/types/analytics.js +14 -0
- package/build/types/facets.d.ts +13 -0
- package/build/types/index.d.ts +5 -2
- package/build/types/index.js +5 -1
- package/build/types/scan-choice.d.ts +49 -0
- package/build/types/scan-choice.js +9 -0
- package/build/types/scan-code.d.ts +72 -1
- package/build/types/scan-code.js +30 -1
- package/dashboard/dist/assets/{AdminDashboard-Bv3pHBzn.js → AdminDashboard-DJ3LJQ09.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Bv3pHBzn.js.map → AdminDashboard-DJ3LJQ09.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Dk2zlvDb.js → AgentConfigPage-BMMvaD0z.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-Dk2zlvDb.js.map → AgentConfigPage-BMMvaD0z.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DUno6EGs.js → AgentDetailPage-C6wfsnRe.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-DUno6EGs.js.map → AgentDetailPage-C6wfsnRe.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-Cwqka7nE.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-CToVu1qj.js.map → AgentsPage-Cwqka7nE.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-CVlG_AVC.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-CVlG_AVC.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-DQOpVB4M.js → BotPicker-BBkJBXZB.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-DQOpVB4M.js.map → BotPicker-BBkJBXZB.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-Dmf46PUJ.js → CapabilitiesPage-wxmE4917.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-Dmf46PUJ.js.map → CapabilitiesPage-wxmE4917.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CDADefUY.js → CollapsibleSection-B3FsrHwH.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CDADefUY.js.map → CollapsibleSection-B3FsrHwH.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-B3nCqJdC.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-B3nCqJdC.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-8LIEvomi.js → CredentialsPage-Bv875IHe.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-8LIEvomi.js.map → CredentialsPage-Bv875IHe.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CK3WSsM5.js → CronLabel-CSzjWuwj.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CK3WSsM5.js.map → CronLabel-CSzjWuwj.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-FPmlA6cE.js → CustomDurationPicker-CCpqf3e4.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-FPmlA6cE.js.map → CustomDurationPicker-CCpqf3e4.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-CL9gA7pu.js → DropZone-CJkk-U3o.js} +2 -2
- package/dashboard/dist/assets/{DropZone-CL9gA7pu.js.map → DropZone-CJkk-U3o.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BZVkVxE0.js → ElapsedCell-WV6pUaKo.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BZVkVxE0.js.map → ElapsedCell-WV6pUaKo.js.map} +1 -1
- package/dashboard/dist/assets/EntityTimelinePanel-DrL86Yrf.js +2 -0
- package/dashboard/dist/assets/EntityTimelinePanel-DrL86Yrf.js.map +1 -0
- package/dashboard/dist/assets/{EscalationListSchemaPage-kYLdUtZX.js → EscalationListSchemaPage-CTQCALw4.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-kYLdUtZX.js.map → EscalationListSchemaPage-CTQCALw4.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-kUmCDivo.js → EscalationSchemaPage-D_UgP0pv.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-kUmCDivo.js.map → EscalationSchemaPage-D_UgP0pv.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-D17auO-m.js → EscalationsOverview-DuIUyxr0.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-D17auO-m.js.map → EscalationsOverview-DuIUyxr0.js.map} +1 -1
- package/dashboard/dist/assets/EventTable-BV6unphX.js +2 -0
- package/dashboard/dist/assets/EventTable-BV6unphX.js.map +1 -0
- package/dashboard/dist/assets/FilterBar-DYFgzXNB.js +2 -0
- package/dashboard/dist/assets/FilterBar-DYFgzXNB.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-D11uOnZi.js → GraphInvokePage-BGHVUipJ.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-D11uOnZi.js.map → GraphInvokePage-BGHVUipJ.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-B-S2cK3E.js +2 -0
- package/dashboard/dist/assets/{HomePage-Bcq10Bxx.js.map → HomePage-B-S2cK3E.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-Bl7F3A28.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-IPXsTb3Q.js.map → ListToolbar-Bl7F3A28.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-Dx2j0KkF.js → McpOverview-_T9IsCD_.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-Dx2j0KkF.js.map → McpOverview-_T9IsCD_.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-CzF_bna8.js → McpQueryDetailPage-DtsVqKPw.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-CzF_bna8.js.map → McpQueryDetailPage-DtsVqKPw.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-DX5u-1bx.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-CNsuiw_q.js.map → McpQueryPage-DX5u-1bx.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-BhcqqtYS.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-BhcqqtYS.js.map +1 -0
- package/dashboard/dist/assets/{McpRunsPage-CK96s3Nt.js → McpRunsPage-L-1y8wnX.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CK96s3Nt.js.map → McpRunsPage-L-1y8wnX.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-B9Vc_Pz2.js → NamespacePill-in1SLd0W.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-B9Vc_Pz2.js.map → NamespacePill-in1SLd0W.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-i8KcDpKo.js +3 -0
- package/dashboard/dist/assets/OperationsPage-i8KcDpKo.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-CIbDzOlh.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-C-jE0IRA.js.map → OperatorDashboard-CIbDzOlh.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Ce4GcIYo.js → PageHeader-BJgWMZtw.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Ce4GcIYo.js.map → PageHeader-BJgWMZtw.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-Ck0KZvXD.js → PageHeaderWithStats-Ccio4vyG.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-Ck0KZvXD.js.map → PageHeaderWithStats-Ccio4vyG.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-CJ6jqo7h.js → PersonaDetailPage-BOaf0TW1.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-CJ6jqo7h.js.map → PersonaDetailPage-BOaf0TW1.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-D8hL3kL5.js → PersonasPage-DSdRb90f.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-D8hL3kL5.js.map → PersonasPage-DSdRb90f.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-Vnx8Z5_y.js → ProcessDetailPage-DN9NqfeP.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-Vnx8Z5_y.js.map → ProcessDetailPage-DN9NqfeP.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DRYtvS3N.js → ProcessesListPage-CfQEWaD4.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DRYtvS3N.js.map → ProcessesListPage-CfQEWaD4.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-BC5HL7ls.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-BC5HL7ls.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-CnuBPhPw.js → RolePill-BNAP-uK6.js} +2 -2
- package/dashboard/dist/assets/{RolePill-CnuBPhPw.js.map → RolePill-BNAP-uK6.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-DCnW0VmD.js +2 -0
- package/dashboard/dist/assets/RolesPage-DCnW0VmD.js.map +1 -0
- package/dashboard/dist/assets/RunAsSelector-twbuX7fB.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-CS3KQ-BF.js.map → RunAsSelector-twbuX7fB.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-CPNg6K--.js +2 -0
- package/dashboard/dist/assets/ScanCodesPage-CPNg6K--.js.map +1 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-DyLmCamO.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-DyLmCamO.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-DoZccU5B.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-DoZccU5B.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-BUpYpS3x.js → ScopeBadge-BG7KkZ8Q.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-BUpYpS3x.js.map → ScopeBadge-BG7KkZ8Q.js.map} +1 -1
- package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js +2 -0
- package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js.map +1 -0
- package/dashboard/dist/assets/StickyPagination-DIeYMPPd.js +2 -0
- package/dashboard/dist/assets/StickyPagination-DIeYMPPd.js.map +1 -0
- package/dashboard/dist/assets/{StreamMessageDetail-DyJyZwBl.js → StreamMessageDetail-gU4CUeQI.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DyJyZwBl.js.map → StreamMessageDetail-gU4CUeQI.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BlzV74V5.js → SwimlaneTimeline-Br-nBA4l.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BlzV74V5.js.map → SwimlaneTimeline-Br-nBA4l.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-BbZ25nNe.js → TagInput-CvM5n6ww.js} +2 -2
- package/dashboard/dist/assets/{TagInput-BbZ25nNe.js.map → TagInput-CvM5n6ww.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-B0p_Z4J_.js → TaskDetailPage-_9cr_R0u.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-B0p_Z4J_.js.map → TaskDetailPage-_9cr_R0u.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-D0QKBrN3.js → TaskQueuePill-D4JPHXOq.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-D0QKBrN3.js.map → TaskQueuePill-D4JPHXOq.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CiGR2QiQ.js → TasksListPage-DVENC9Jp.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CiGR2QiQ.js.map → TasksListPage-DVENC9Jp.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-D_DA9ucC.js → TimeAgo-C9yYnOui.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-D_DA9ucC.js.map → TimeAgo-C9yYnOui.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-C7rkC9nh.js → TimestampCell-DoB8cYgw.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-C7rkC9nh.js.map → TimestampCell-DoB8cYgw.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-8xY9rkoc.js → ToolPill-BUjbC-Tj.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-8xY9rkoc.js.map → ToolPill-BUjbC-Tj.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-E8efYGYs.js → ToolTestPanel-CBtsIP8K.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-E8efYGYs.js.map → ToolTestPanel-CBtsIP8K.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-B455XrRc.js → TopicDetailPage-mR4Jaz83.js} +4 -4
- package/dashboard/dist/assets/{TopicDetailPage-B455XrRc.js.map → TopicDetailPage-mR4Jaz83.js.map} +1 -1
- package/dashboard/dist/assets/TopicsPage-CP7HFxIC.js +2 -0
- package/dashboard/dist/assets/{TopicsPage-1VAc29Qw.js.map → TopicsPage-CP7HFxIC.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DikzjQHJ.js → UserName-BnLF6yhz.js} +2 -2
- package/dashboard/dist/assets/{UserName-DikzjQHJ.js.map → UserName-BnLF6yhz.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-xL956RZi.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-xL956RZi.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowPill-Da406nEj.js → WorkflowPill-tXU0-eXu.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Da406nEj.js.map → WorkflowPill-tXU0-eXu.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-B-u7zFKM.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-BMQd_0tW.js.map → WorkflowsDashboard-B-u7zFKM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-CdxjVifp.js → WorkflowsOverview-CqZVarK-.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CdxjVifp.js.map → WorkflowsOverview-CqZVarK-.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DNVffIXa.js → YamlWorkflowDetailPage-DiFLavW0.js} +10 -10
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DNVffIXa.js.map → YamlWorkflowDetailPage-DiFLavW0.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BGP8wuos.js → YamlWorkflowsPage-BuQM6uZA.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BGP8wuos.js.map → YamlWorkflowsPage-BuQM6uZA.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BZJLIJ4h.js → agents-DU9GPovp.js} +2 -2
- package/dashboard/dist/assets/{agents-BZJLIJ4h.js.map → agents-DU9GPovp.js.map} +1 -1
- package/dashboard/dist/assets/{bots-ClLcDGJb.js → bots-Cy-Hmg7w.js} +2 -2
- package/dashboard/dist/assets/{bots-ClLcDGJb.js.map → bots-Cy-Hmg7w.js.map} +1 -1
- package/dashboard/dist/assets/capabilities-sSJJqrp-.js +2 -0
- package/dashboard/dist/assets/{capabilities-IaCcS7ge.js.map → capabilities-sSJJqrp-.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Zi4m_MSx.js → controlplane-TVCjDHQ-.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Zi4m_MSx.js.map → controlplane-TVCjDHQ-.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-BpkjKYGd.js +2 -0
- package/dashboard/dist/assets/escalation-columns-BpkjKYGd.js.map +1 -0
- package/dashboard/dist/assets/index-5TblaCXQ.css +1 -0
- package/dashboard/dist/assets/index-7BP6FaCZ.js +2 -0
- package/dashboard/dist/assets/{index-Dldi3Q3M.js.map → index-7BP6FaCZ.js.map} +1 -1
- package/dashboard/dist/assets/{index-BzkE48xJ.js → index-B7IaBPBg.js} +4 -4
- package/dashboard/dist/assets/{index-BzkE48xJ.js.map → index-B7IaBPBg.js.map} +1 -1
- package/dashboard/dist/assets/index-BE0phFw0.js +2 -0
- package/dashboard/dist/assets/{index-CLmZaNTK.js.map → index-BE0phFw0.js.map} +1 -1
- package/dashboard/dist/assets/{index-BqGnhkh0.js → index-BYNN9N1T.js} +2 -2
- package/dashboard/dist/assets/{index-BqGnhkh0.js.map → index-BYNN9N1T.js.map} +1 -1
- package/dashboard/dist/assets/{index-kiKZresb.js → index-CLPVqbVY.js} +2 -2
- package/dashboard/dist/assets/{index-kiKZresb.js.map → index-CLPVqbVY.js.map} +1 -1
- package/dashboard/dist/assets/{index-C3o4OisO.js → index-Cfv86_L9.js} +2 -2
- package/dashboard/dist/assets/{index-C3o4OisO.js.map → index-Cfv86_L9.js.map} +1 -1
- package/dashboard/dist/assets/{index-yGNt29V9.js → index-CtwbQ_-m.js} +2 -2
- package/dashboard/dist/assets/{index-yGNt29V9.js.map → index-CtwbQ_-m.js.map} +1 -1
- package/dashboard/dist/assets/index-DOai950R.js +3 -0
- package/dashboard/dist/assets/index-DOai950R.js.map +1 -0
- package/dashboard/dist/assets/index-DTtHNC-D.js +5 -0
- package/dashboard/dist/assets/{index-CvNBdkB1.js.map → index-DTtHNC-D.js.map} +1 -1
- package/dashboard/dist/assets/{index-CJu2PBNx.js → index-DsWnVyVN.js} +2 -2
- package/dashboard/dist/assets/{index-CJu2PBNx.js.map → index-DsWnVyVN.js.map} +1 -1
- package/dashboard/dist/assets/{index-D0zFReGL.js → index-Dy-MMYti.js} +2 -2
- package/dashboard/dist/assets/{index-D0zFReGL.js.map → index-Dy-MMYti.js.map} +1 -1
- package/dashboard/dist/assets/index-errgQT5x.js +65 -0
- package/dashboard/dist/assets/index-errgQT5x.js.map +1 -0
- package/dashboard/dist/assets/{index-CmnNqpWg.js → index-fgBDhnI6.js} +2 -2
- package/dashboard/dist/assets/{index-CmnNqpWg.js.map → index-fgBDhnI6.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-DWLxGTib.js → knowledge-arh4NfmL.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DWLxGTib.js.map → knowledge-arh4NfmL.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-B6AARZ2I.js → mcp-QGf5jHCo.js} +2 -2
- package/dashboard/dist/assets/{mcp-B6AARZ2I.js.map → mcp-QGf5jHCo.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-DrkvBU3a.js → mcp-query-BEJN1nMZ.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-DrkvBU3a.js.map → mcp-query-BEJN1nMZ.js.map} +1 -1
- package/dashboard/dist/assets/{personas-Cmz2SAEU.js → personas-DYtw1COf.js} +2 -2
- package/dashboard/dist/assets/{personas-Cmz2SAEU.js.map → personas-DYtw1COf.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-CSgfVCMy.js → pipelines-Byi6PnbE.js} +2 -2
- package/dashboard/dist/assets/{pipelines-CSgfVCMy.js.map → pipelines-Byi6PnbE.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-UOtUkDk-.js → tasks-D0SQdENz.js} +2 -2
- package/dashboard/dist/assets/{tasks-UOtUkDk-.js.map → tasks-D0SQdENz.js.map} +1 -1
- package/dashboard/dist/assets/{topics-Df5hGh6o.js → topics-DgDv5ZXP.js} +2 -2
- package/dashboard/dist/assets/{topics-Df5hGh6o.js.map → topics-DgDv5ZXP.js.map} +1 -1
- package/dashboard/dist/assets/useEventHooks-DZaYzE7s.js +2 -0
- package/dashboard/dist/assets/{useEventHooks-PDbuSJ12.js.map → useEventHooks-DZaYzE7s.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-tZSOlge3.js → useNamespace-C1OqiNXN.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-tZSOlge3.js.map → useNamespace-C1OqiNXN.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-CINLzE32.js → useYamlActivityEvents-CkmXDm-Z.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-CINLzE32.js.map → useYamlActivityEvents-CkmXDm-Z.js.map} +1 -1
- package/dashboard/dist/assets/{users-G8qwyZKS.js → users-D4DCFPH1.js} +2 -2
- package/dashboard/dist/assets/{users-G8qwyZKS.js.map → users-D4DCFPH1.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-BpZiWH2f.js → vendor-icons-BxuyFxH2.js} +156 -136
- package/dashboard/dist/assets/vendor-icons-BxuyFxH2.js.map +1 -0
- package/dashboard/dist/assets/{workflows-DbPqi1TW.js → workflows-qyc0ku_5.js} +2 -2
- package/dashboard/dist/assets/{workflows-DbPqi1TW.js.map → workflows-qyc0ku_5.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DozD8hpR.js → yaml-workflows-DWFww9Xn.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DozD8hpR.js.map → yaml-workflows-DWFww9Xn.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/escalations.md +133 -0
- package/docs/api/http/roles.md +6 -0
- package/docs/api/mcp/admin.md +53 -0
- package/docs/api/sdk/escalations.md +58 -0
- package/docs/cli.md +11 -0
- package/docs/dashboard.md +22 -20
- package/docs/data.md +12 -4
- package/docs/design-principles.md +9 -7
- package/docs/escalation-analytics.md +251 -0
- package/docs/hitl/roles.md +1 -1
- package/docs/hitl/x-lt-embed.md +8 -4
- package/docs/hitl/x-lt-footer.md +67 -0
- package/docs/hitl/x-lt-list-schema.md +10 -3
- package/docs/hitl-guide.md +11 -2
- package/docs/iam.md +12 -0
- package/docs/operations.md +17 -0
- package/docs/scan-codes.md +112 -0
- package/docs/sdk.md +1 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/AgentsPage-CToVu1qj.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DldboL4W.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DldboL4W.js.map +0 -1
- package/dashboard/dist/assets/CountdownTimer-DPjIkerB.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-DPjIkerB.js.map +0 -1
- package/dashboard/dist/assets/EventTable-CwPWl163.js +0 -2
- package/dashboard/dist/assets/EventTable-CwPWl163.js.map +0 -1
- package/dashboard/dist/assets/FilterBar-D7GghUsU.js +0 -2
- package/dashboard/dist/assets/FilterBar-D7GghUsU.js.map +0 -1
- package/dashboard/dist/assets/HomePage-Bcq10Bxx.js +0 -2
- package/dashboard/dist/assets/ListToolbar-IPXsTb3Q.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-CNsuiw_q.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-BJguEMS0.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-BJguEMS0.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-DvWrLuH6.js +0 -2
- package/dashboard/dist/assets/OperationsPage-DvWrLuH6.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-C-jE0IRA.js +0 -2
- package/dashboard/dist/assets/RoleDetailPage-BKkUvTO-.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-BKkUvTO-.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-BHzWK9n6.js +0 -2
- package/dashboard/dist/assets/RolesPage-BHzWK9n6.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-CS3KQ-BF.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-BW4P4zWf.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-BW4P4zWf.js.map +0 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-BLykA4j-.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-BLykA4j-.js.map +0 -1
- package/dashboard/dist/assets/StickyPagination-hMrnLXde.js +0 -2
- package/dashboard/dist/assets/StickyPagination-hMrnLXde.js.map +0 -1
- package/dashboard/dist/assets/TopicsPage-1VAc29Qw.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-C15GSAoe.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-C15GSAoe.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-BMQd_0tW.js +0 -2
- package/dashboard/dist/assets/capabilities-IaCcS7ge.js +0 -2
- package/dashboard/dist/assets/escalation-columns-BY2mg9DY.js +0 -2
- package/dashboard/dist/assets/escalation-columns-BY2mg9DY.js.map +0 -1
- package/dashboard/dist/assets/index-CLmZaNTK.js +0 -2
- package/dashboard/dist/assets/index-CfAi1OsI.js +0 -65
- package/dashboard/dist/assets/index-CfAi1OsI.js.map +0 -1
- package/dashboard/dist/assets/index-CvNBdkB1.js +0 -5
- package/dashboard/dist/assets/index-Dldi3Q3M.js +0 -2
- package/dashboard/dist/assets/index-mKcQGi2B.js +0 -3
- package/dashboard/dist/assets/index-mKcQGi2B.js.map +0 -1
- package/dashboard/dist/assets/index-zQiUPfxA.css +0 -1
- package/dashboard/dist/assets/useEventHooks-PDbuSJ12.js +0 -2
- package/dashboard/dist/assets/vendor-icons-BpZiWH2f.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Durable platforms are built around determinism — that is their strength and their blind spot. They give you rich, first-class queues for deterministic work (retry, timeout, `backoffCoefficient`, exactly-once) and an `await condition()` to park a workflow until a signal arrives. All of it assumes the thing you are waiting on will, eventually, behave.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Long Tail makes it a primitive. The same `condition()` wait — except the act of waiting mints a row that is searchable, claimable, deadlined, and role-gated on a shared metadata surface. Machines answer some rows, people answer others; the workflow resumes either way, exactly where it paused.
|
|
7
|
+
Long Tail makes non-determinism a primitive. The same `condition()` wait — except the act of waiting mints a row that is searchable, claimable, deadlined, and role-gated on a shared metadata surface. Machines answer some rows, people answer others; the workflow resumes either way, exactly where it paused.
|
|
10
8
|
|
|
11
9
|
```bash
|
|
12
10
|
npm install @hotmeshio/long-tail
|
|
@@ -14,7 +12,7 @@ npm install @hotmeshio/long-tail
|
|
|
14
12
|
|
|
15
13
|
## How it works
|
|
16
14
|
|
|
17
|
-
One workflow, both queues: `proxyActivities` for the deterministic one, `condition()` for
|
|
15
|
+
One workflow, both queues: `proxyActivities` for the deterministic one, `condition()` for non-determinism.
|
|
18
16
|
|
|
19
17
|
```typescript
|
|
20
18
|
import { Durable } from '@hotmeshio/hotmesh';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
2
|
+
import type { AggregateByFacetsInput, TimelineByFacetInput } from '../../types';
|
|
3
|
+
/** Grouped membership/dwell aggregate over the escalation intervals. */
|
|
4
|
+
export declare function aggregateByFacets(input: AggregateByFacetsInput, auth: LTApiAuth): Promise<LTApiResult>;
|
|
5
|
+
/** One entity's ordered interval sequence (gap-preserving). */
|
|
6
|
+
export declare function timelineByFacet(input: TimelineByFacetInput, auth: LTApiAuth): Promise<LTApiResult>;
|
|
@@ -0,0 +1,123 @@
|
|
|
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.aggregateByFacets = aggregateByFacets;
|
|
37
|
+
exports.timelineByFacet = timelineByFacet;
|
|
38
|
+
const escalationService = __importStar(require("../../services/escalation"));
|
|
39
|
+
const escalation_1 = require("../../services/escalation");
|
|
40
|
+
const userService = __importStar(require("../../services/user"));
|
|
41
|
+
const features_1 = require("../../modules/features");
|
|
42
|
+
// ── Escalation analytics surface (public) ────────────────────────────────────
|
|
43
|
+
//
|
|
44
|
+
// Grouped/temporal reads over the pond (membership, dwell, timeline). Reads
|
|
45
|
+
// only, but reads that AGGREGATE other operators' items — so the gate is the
|
|
46
|
+
// same broad scope the faceted search uses (read_all per requested role), with
|
|
47
|
+
// one extension: these queries may span roles. A caller must hold read_all on
|
|
48
|
+
// EVERY role in the filter; a filter with no role scope is inherently
|
|
49
|
+
// cross-role and requires a global principal (superadmin / admin). Results are
|
|
50
|
+
// principal-independent once the gate passes, which is what makes the
|
|
51
|
+
// service-layer cache shareable.
|
|
52
|
+
//
|
|
53
|
+
// publicPaceBoard carve-out (mirrors GET /station-metrics, list.ts): with the
|
|
54
|
+
// flag on, any authenticated caller may run aggregates whose group keys are
|
|
55
|
+
// COLUMNS only — those emit counts/seconds, the exact data class the Pace
|
|
56
|
+
// Board already exposes to every login. A groupBy.facets grouping emits facet
|
|
57
|
+
// VALUES (entity ids) as group keys and always takes the strict gate, as does
|
|
58
|
+
// timelineByFacet (an entity's movement history is item-level disclosure).
|
|
59
|
+
async function callerMayReadPonds(userId, roles) {
|
|
60
|
+
if (await userService.hasGlobalEscalationAccess(userId))
|
|
61
|
+
return true;
|
|
62
|
+
if (!roles.length)
|
|
63
|
+
return false; // whole-pond / cross-role ⇒ global only
|
|
64
|
+
for (const role of roles) {
|
|
65
|
+
const scope = await userService.getRoleScope(userId, role);
|
|
66
|
+
if (scope?.read !== 'all')
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
async function effectiveRoles(query) {
|
|
72
|
+
// `entity` scopes to its derived system — the gate covers the same roles the
|
|
73
|
+
// query will actually touch. Resolution throws AnalyticsInputError (→ 400)
|
|
74
|
+
// for unknown keys, before any scope decision.
|
|
75
|
+
if (query?.entity) {
|
|
76
|
+
return (await escalationService.resolveEntitySystem(query.entity)).map((s) => s.role);
|
|
77
|
+
}
|
|
78
|
+
if (query?.role)
|
|
79
|
+
return [query.role];
|
|
80
|
+
if (query?.roles?.length)
|
|
81
|
+
return query.roles;
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
function deniedMessage(roles) {
|
|
85
|
+
return roles.length
|
|
86
|
+
? `You must hold ${roles.map((r) => `"${r}"`).join(', ')} with full (read_all) scope or be a superadmin`
|
|
87
|
+
: 'Analytics without a role filter spans every pond — a global (superadmin/admin) principal is required';
|
|
88
|
+
}
|
|
89
|
+
function failure(err) {
|
|
90
|
+
if (err instanceof escalation_1.AnalyticsInputError)
|
|
91
|
+
return { status: 400, error: err.message };
|
|
92
|
+
return { status: 500, error: err.message };
|
|
93
|
+
}
|
|
94
|
+
/** Grouped membership/dwell aggregate over the escalation intervals. */
|
|
95
|
+
async function aggregateByFacets(input, auth) {
|
|
96
|
+
try {
|
|
97
|
+
const roles = await effectiveRoles(input?.query);
|
|
98
|
+
const countsOnly = !input?.groupBy?.facets?.length;
|
|
99
|
+
const publiclyReadable = countsOnly && (0, features_1.getFeatureFlags)().publicPaceBoard;
|
|
100
|
+
if (!publiclyReadable && !(await callerMayReadPonds(auth.userId, roles))) {
|
|
101
|
+
return { status: 403, error: deniedMessage(roles) };
|
|
102
|
+
}
|
|
103
|
+
const data = await escalationService.aggregateByFacets(input);
|
|
104
|
+
return { status: 200, data };
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
return failure(err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** One entity's ordered interval sequence (gap-preserving). */
|
|
111
|
+
async function timelineByFacet(input, auth) {
|
|
112
|
+
try {
|
|
113
|
+
const roles = await effectiveRoles(input?.query);
|
|
114
|
+
if (!(await callerMayReadPonds(auth.userId, roles))) {
|
|
115
|
+
return { status: 403, error: deniedMessage(roles) };
|
|
116
|
+
}
|
|
117
|
+
const data = await escalationService.timelineByFacet(input);
|
|
118
|
+
return { status: 200, data };
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
return failure(err);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -7,3 +7,4 @@ export { resolveEscalation, resolveBySignalKey, resolveByIds, resolveAllOrNone }
|
|
|
7
7
|
export { findByMetadata, claimByMetadata, resolveByMetadata } from './metadata';
|
|
8
8
|
export { cancelSingleEscalation, bulkCancel } from './cancel';
|
|
9
9
|
export { searchByFacets, claimGroups, claimByFacets } from './facets';
|
|
10
|
+
export { aggregateByFacets, timelineByFacet } from './analytics';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.claimByFacets = exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
|
|
3
|
+
exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
|
|
4
4
|
var create_1 = require("./create");
|
|
5
5
|
Object.defineProperty(exports, "createEscalation", { enumerable: true, get: function () { return create_1.createEscalation; } });
|
|
6
6
|
var list_1 = require("./list");
|
|
@@ -40,3 +40,6 @@ var facets_1 = require("./facets");
|
|
|
40
40
|
Object.defineProperty(exports, "searchByFacets", { enumerable: true, get: function () { return facets_1.searchByFacets; } });
|
|
41
41
|
Object.defineProperty(exports, "claimGroups", { enumerable: true, get: function () { return facets_1.claimGroups; } });
|
|
42
42
|
Object.defineProperty(exports, "claimByFacets", { enumerable: true, get: function () { return facets_1.claimByFacets; } });
|
|
43
|
+
var analytics_1 = require("./analytics");
|
|
44
|
+
Object.defineProperty(exports, "aggregateByFacets", { enumerable: true, get: function () { return analytics_1.aggregateByFacets; } });
|
|
45
|
+
Object.defineProperty(exports, "timelineByFacet", { enumerable: true, get: function () { return analytics_1.timelineByFacet; } });
|
|
@@ -161,7 +161,7 @@ async function resolveByMetadata(input, auth) {
|
|
|
161
161
|
const enforcing = await (0, enforcement_cache_1.getEnforcingRoles)();
|
|
162
162
|
let result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, writeAllRoles, writeSelfRoles, enforcing.size > 0 ? [...enforcing] : null, null, input.extraFacets);
|
|
163
163
|
if (result.outcome === 'validation_required' && result.row) {
|
|
164
|
-
const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload);
|
|
164
|
+
const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload, undefined, resolveUserId);
|
|
165
165
|
if (report)
|
|
166
166
|
return (0, resolve_1.validationFailure)(report);
|
|
167
167
|
result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, writeAllRoles, writeSelfRoles, null, result.row.id, input.extraFacets);
|
|
@@ -98,7 +98,7 @@ async function resolveEscalation(input, auth) {
|
|
|
98
98
|
// the escalation's resolved form schema BEFORE any resolution path runs.
|
|
99
99
|
// Costs nothing when the role does not enforce (cached role set); the
|
|
100
100
|
// task-fallback envelope read only happens for enforcing roles.
|
|
101
|
-
const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation));
|
|
101
|
+
const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation), auth.userId);
|
|
102
102
|
if (violation)
|
|
103
103
|
return validationFailure(violation);
|
|
104
104
|
// The resolver payload is stored exactly as submitted — its shape is the
|
|
@@ -181,7 +181,7 @@ async function resolveBySignalKey(input, auth) {
|
|
|
181
181
|
return { status: 404, error: 'Escalation not found' };
|
|
182
182
|
// Schema enforcement — the row (envelope included) is already loaded, so
|
|
183
183
|
// this costs zero extra reads beyond the cached schema.
|
|
184
|
-
const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload);
|
|
184
|
+
const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, undefined, auth.userId);
|
|
185
185
|
if (violation)
|
|
186
186
|
return validationFailure(violation);
|
|
187
187
|
// The payload is delivered as the signal the parked workflow's condition()
|
|
@@ -247,7 +247,7 @@ async function resolveByIds(input, auth) {
|
|
|
247
247
|
const fullRows = await escalationService.getEscalationsByIds(involved);
|
|
248
248
|
const failed = [];
|
|
249
249
|
for (const row of fullRows) {
|
|
250
|
-
const report = await (0, resolver_validation_1.checkResolverPayload)(row, resolverPayload);
|
|
250
|
+
const report = await (0, resolver_validation_1.checkResolverPayload)(row, resolverPayload, undefined, auth.userId);
|
|
251
251
|
if (report)
|
|
252
252
|
failed.push({ id: row.id, report });
|
|
253
253
|
}
|
|
@@ -346,7 +346,7 @@ async function resolveAllOrNone(input, auth) {
|
|
|
346
346
|
const row = rowById.get(item.id);
|
|
347
347
|
if (!row || !row.role || !enforcing.has(row.role))
|
|
348
348
|
continue;
|
|
349
|
-
const report = await (0, resolver_validation_1.checkResolverPayload)(row, item.resolverPayload);
|
|
349
|
+
const report = await (0, resolver_validation_1.checkResolverPayload)(row, item.resolverPayload, undefined, auth.userId);
|
|
350
350
|
if (report)
|
|
351
351
|
failed.push({ id: item.id, report });
|
|
352
352
|
}
|
package/build/api/roles.d.ts
CHANGED
|
@@ -106,6 +106,10 @@ export declare function updateRole(input: {
|
|
|
106
106
|
priority_threshold_minutes?: number | null;
|
|
107
107
|
/** Escalation metadata key holding the age origin (ISO 8601 UTC timestamp). Falls back to created_at. */
|
|
108
108
|
priority_facet?: string | null;
|
|
109
|
+
/** Escalation metadata key identifying the entity that moves through this role (e.g. serialNumber). */
|
|
110
|
+
entity_facet?: string | null;
|
|
111
|
+
/** How this role names the entity's states: 'role' (the station is the state) or 'subtype'. Null resets to 'role'. */
|
|
112
|
+
entity_state_source?: 'role' | 'subtype' | null;
|
|
109
113
|
/** Turn server-side resolver schema validation on/off for this role. */
|
|
110
114
|
enforce_schema?: boolean;
|
|
111
115
|
/** Replace the upstream-input set (omitted = preserve; null or [] = clear). */
|
package/build/api/roles.js
CHANGED
|
@@ -222,6 +222,12 @@ async function updateRole(input) {
|
|
|
222
222
|
if (input.priority_facet != null && (typeof input.priority_facet !== 'string' || !facet_sql_1.FACET_KEY.test(input.priority_facet))) {
|
|
223
223
|
return { status: 400, error: 'priority_facet must be a metadata key (letters, numbers, underscores) or null' };
|
|
224
224
|
}
|
|
225
|
+
if (input.entity_facet != null && (typeof input.entity_facet !== 'string' || !facet_sql_1.FACET_KEY.test(input.entity_facet))) {
|
|
226
|
+
return { status: 400, error: 'entity_facet must be a metadata key (letters, numbers, underscores) or null' };
|
|
227
|
+
}
|
|
228
|
+
if (input.entity_state_source != null && input.entity_state_source !== 'role' && input.entity_state_source !== 'subtype') {
|
|
229
|
+
return { status: 400, error: "entity_state_source must be 'role', 'subtype', or null" };
|
|
230
|
+
}
|
|
225
231
|
if (input.ops_visible !== undefined && typeof input.ops_visible !== 'boolean') {
|
|
226
232
|
return { status: 400, error: 'ops_visible must be a boolean' };
|
|
227
233
|
}
|
|
@@ -272,6 +278,8 @@ async function updateRole(input) {
|
|
|
272
278
|
worker_count: input.worker_count,
|
|
273
279
|
priority_threshold_minutes: input.priority_threshold_minutes,
|
|
274
280
|
priority_facet: input.priority_facet,
|
|
281
|
+
entity_facet: input.entity_facet,
|
|
282
|
+
entity_state_source: input.entity_state_source,
|
|
275
283
|
enforce_schema: input.enforce_schema,
|
|
276
284
|
upstream_roles: input.upstream_roles,
|
|
277
285
|
change_summary: input.change_summary,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ScanChoiceExecuteRequest, type ScanExecuteResponse } from '../../types';
|
|
2
|
+
import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Execute one presented choice. The request is a POINTER — scheme/category/
|
|
5
|
+
* step/choice indices plus the escalation id the screen showed — and a
|
|
6
|
+
* pointer is never authority: the choice is re-read from live config, the
|
|
7
|
+
* row is re-located under the step's query, the identity gate re-applies,
|
|
8
|
+
* and the verb runs through the same atomic executors a direct scan uses
|
|
9
|
+
* (so a lost race is a structured CONFLICT, exactly as on double-scan).
|
|
10
|
+
*/
|
|
11
|
+
export declare function executeScanChoice(input: ScanChoiceExecuteRequest, auth: LTApiAuth): Promise<LTApiResult<ScanExecuteResponse>>;
|
|
@@ -0,0 +1,136 @@
|
|
|
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.executeScanChoice = executeScanChoice;
|
|
37
|
+
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
38
|
+
const escalationService = __importStar(require("../../services/escalation"));
|
|
39
|
+
const types_1 = require("../../types");
|
|
40
|
+
const identity_1 = require("./identity");
|
|
41
|
+
const context_1 = require("./context");
|
|
42
|
+
const locate_1 = require("./locate");
|
|
43
|
+
const verbs_1 = require("./verbs");
|
|
44
|
+
/**
|
|
45
|
+
* Execute one presented choice. The request is a POINTER — scheme/category/
|
|
46
|
+
* step/choice indices plus the escalation id the screen showed — and a
|
|
47
|
+
* pointer is never authority: the choice is re-read from live config, the
|
|
48
|
+
* row is re-located under the step's query, the identity gate re-applies,
|
|
49
|
+
* and the verb runs through the same atomic executors a direct scan uses
|
|
50
|
+
* (so a lost race is a structured CONFLICT, exactly as on double-scan).
|
|
51
|
+
*/
|
|
52
|
+
async function executeScanChoice(input, auth) {
|
|
53
|
+
try {
|
|
54
|
+
if (!Number.isInteger(input?.schemeVersion) || typeof input?.category !== 'string'
|
|
55
|
+
|| !Number.isInteger(input?.stepIndex) || !Number.isInteger(input?.choiceIndex)
|
|
56
|
+
|| !input?.escalationId) {
|
|
57
|
+
return { status: 400, error: 'schemeVersion, category, stepIndex, choiceIndex, and escalationId are required' };
|
|
58
|
+
}
|
|
59
|
+
// 1. The pointer resolves against LIVE config — an edit between render
|
|
60
|
+
// and tap is a structured miss, never a stale execution.
|
|
61
|
+
const scheme = await scanCodeService.getScanScheme(input.schemeVersion);
|
|
62
|
+
const rule = await scanCodeService.getScanRule(input.schemeVersion, input.category);
|
|
63
|
+
const step = rule?.steps?.[input.stepIndex];
|
|
64
|
+
const choice = step?.choices?.[input.choiceIndex];
|
|
65
|
+
if (!scheme || !scheme.enabled || scheme.kind !== types_1.SCAN_SCHEME_KINDS.ACTION
|
|
66
|
+
|| !rule || !rule.enabled || step?.verb !== types_1.SCAN_VERBS.PRESENT || !choice) {
|
|
67
|
+
return {
|
|
68
|
+
status: 200,
|
|
69
|
+
data: { outcome: types_1.SCAN_OUTCOMES.UNCONFIGURED, error: 'the presented choice is no longer configured' },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// 2. The acting grant, exchanged before anything reads or writes.
|
|
73
|
+
let effectiveAuth = auth;
|
|
74
|
+
let acting = false;
|
|
75
|
+
if (input.actingToken) {
|
|
76
|
+
const resolved = await (0, identity_1.resolveActingAuth)(input.actingToken);
|
|
77
|
+
if (!resolved.ok) {
|
|
78
|
+
return {
|
|
79
|
+
status: 200,
|
|
80
|
+
data: { outcome: types_1.SCAN_OUTCOMES.NOT_PRIMED, notPrimed: rule.notPrimed, error: resolved.error },
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
effectiveAuth = resolved.auth;
|
|
84
|
+
acting = true;
|
|
85
|
+
}
|
|
86
|
+
// 3. The row anchors the target: the scheme's facet on the escalation the
|
|
87
|
+
// screen presented. A missing binding is loud misconfiguration.
|
|
88
|
+
const row = await escalationService.getEscalation(input.escalationId);
|
|
89
|
+
const target = row?.metadata?.[scheme.target_facet];
|
|
90
|
+
if (!row || typeof target !== 'string' || !target) {
|
|
91
|
+
return {
|
|
92
|
+
status: 200,
|
|
93
|
+
data: { outcome: types_1.SCAN_OUTCOMES.UNCONFIGURED, error: `escalation does not carry the scheme facet "${scheme.target_facet}"` },
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const ctx = {
|
|
97
|
+
scheme,
|
|
98
|
+
rule,
|
|
99
|
+
parsed: { version: scheme.version, category: rule.category, target },
|
|
100
|
+
scannedAt: new Date().toISOString(),
|
|
101
|
+
auth: effectiveAuth,
|
|
102
|
+
stationAuth: auth,
|
|
103
|
+
acting,
|
|
104
|
+
};
|
|
105
|
+
// 4. The identity gate, per the choice.
|
|
106
|
+
if (choice.requireActingIdentity && !(await (0, identity_1.actingIdentitySatisfied)(step, ctx))) {
|
|
107
|
+
return decorate((0, context_1.notPrimed)(ctx), ctx, input);
|
|
108
|
+
}
|
|
109
|
+
// 5. The row must still match the step's query — the reality the screen
|
|
110
|
+
// showed. A row that moved on (resolved, claimed away, re-routed) is the
|
|
111
|
+
// same double-actor race a second scan loses.
|
|
112
|
+
const located = await (0, locate_1.locateForStep)(step, ctx, 2);
|
|
113
|
+
if (!located || !located.escalations.some((e) => e.id === input.escalationId)) {
|
|
114
|
+
return decorate((0, context_1.conflict)('the item is no longer in the presented state'), ctx, input);
|
|
115
|
+
}
|
|
116
|
+
// 6. Dispatch through the same atomic executors a direct scan uses.
|
|
117
|
+
const synthesized = { query: step.query, verb: choice.verb, params: choice.params };
|
|
118
|
+
const result = await (0, verbs_1.dispatchChoiceVerb)(synthesized, ctx, located.escalations[0]);
|
|
119
|
+
return decorate(result, ctx, input);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
return { status: 500, error: err.message };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** Stamp the rule + pointer identity onto the outcome, mirroring execute. */
|
|
126
|
+
function decorate(result, ctx, input) {
|
|
127
|
+
if (result.data && typeof result.data === 'object' && 'outcome' in result.data) {
|
|
128
|
+
result.data = {
|
|
129
|
+
...result.data,
|
|
130
|
+
parsed: ctx.parsed,
|
|
131
|
+
rule: { schemeVersion: ctx.rule.scheme_version, category: ctx.rule.category, name: ctx.rule.name },
|
|
132
|
+
stepIndex: input.stepIndex,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as scanCodeService from '../../services/scan-code';
|
|
2
|
+
import { type LTEscalationRecord, type ParsedScanCode, type ScanExecuteResponse, type ScanRule, type ScanScheme, type ScanStep } from '../../types';
|
|
3
|
+
import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
4
|
+
/** Everything a step executor needs about the scan that reached it. */
|
|
5
|
+
export interface StepContext {
|
|
6
|
+
scheme: ScanScheme;
|
|
7
|
+
rule: ScanRule;
|
|
8
|
+
parsed: ParsedScanCode;
|
|
9
|
+
scannedAt: string;
|
|
10
|
+
/** The effective actor — the acting (badged) user when a grant rode the request. */
|
|
11
|
+
auth: LTApiAuth;
|
|
12
|
+
/** The authenticated principal (the device on a station deployment). */
|
|
13
|
+
stationAuth: LTApiAuth;
|
|
14
|
+
/** True when `auth` came from an acting-identity grant. */
|
|
15
|
+
acting: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function targetFilter(step: ScanStep, ctx: StepContext): Record<string, any>;
|
|
18
|
+
export declare function templateContext(ctx: StepContext): scanCodeService.ScanTemplateContext;
|
|
19
|
+
export declare function provenance(ctx: StepContext): Record<string, any>;
|
|
20
|
+
export declare function interpolatedMetadata(step: ScanStep, ctx: StepContext): Record<string, any>;
|
|
21
|
+
export declare function executed(escalation: LTEscalationRecord | Record<string, any> | undefined, step: Pick<ScanStep, 'verb'>): LTApiResult<ScanExecuteResponse>;
|
|
22
|
+
export declare function forbidden(error?: string): LTApiResult<ScanExecuteResponse>;
|
|
23
|
+
export declare function conflict(error?: string): LTApiResult<ScanExecuteResponse>;
|
|
24
|
+
export declare function notPrimed(ctx: StepContext): LTApiResult<ScanExecuteResponse>;
|
|
@@ -0,0 +1,86 @@
|
|
|
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.targetFilter = targetFilter;
|
|
37
|
+
exports.templateContext = templateContext;
|
|
38
|
+
exports.provenance = provenance;
|
|
39
|
+
exports.interpolatedMetadata = interpolatedMetadata;
|
|
40
|
+
exports.executed = executed;
|
|
41
|
+
exports.forbidden = forbidden;
|
|
42
|
+
exports.conflict = conflict;
|
|
43
|
+
exports.notPrimed = notPrimed;
|
|
44
|
+
const scanCodeService = __importStar(require("../../services/scan-code"));
|
|
45
|
+
const types_1 = require("../../types");
|
|
46
|
+
function targetFilter(step, ctx) {
|
|
47
|
+
return { [ctx.scheme.target_facet]: ctx.parsed.target, ...(step.query?.facets ?? {}) };
|
|
48
|
+
}
|
|
49
|
+
function templateContext(ctx) {
|
|
50
|
+
return { target: ctx.parsed.target, category: ctx.parsed.category, scannedAt: ctx.scannedAt };
|
|
51
|
+
}
|
|
52
|
+
function provenance(ctx) {
|
|
53
|
+
return {
|
|
54
|
+
[types_1.SCAN_PROVENANCE_KEYS.SCHEME]: ctx.scheme.version,
|
|
55
|
+
[types_1.SCAN_PROVENANCE_KEYS.CATEGORY]: ctx.parsed.category,
|
|
56
|
+
[types_1.SCAN_PROVENANCE_KEYS.ACTION_NAME]: ctx.rule.name,
|
|
57
|
+
[types_1.SCAN_PROVENANCE_KEYS.SCANNED_AT]: ctx.scannedAt,
|
|
58
|
+
// Under an acting identity the mutation attributes to the person; the
|
|
59
|
+
// device where it happened is the other half of the audit pair.
|
|
60
|
+
...(ctx.acting ? { [types_1.SCAN_PROVENANCE_KEYS.STATION]: ctx.stationAuth.userId } : {}),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function interpolatedMetadata(step, ctx) {
|
|
64
|
+
return step.params?.metadata
|
|
65
|
+
? scanCodeService.interpolateScanTemplate(step.params.metadata, templateContext(ctx))
|
|
66
|
+
: {};
|
|
67
|
+
}
|
|
68
|
+
function executed(escalation, step) {
|
|
69
|
+
return { status: 200, data: { outcome: types_1.SCAN_OUTCOMES.EXECUTED, verb: step.verb, escalation } };
|
|
70
|
+
}
|
|
71
|
+
function forbidden(error) {
|
|
72
|
+
return { status: 200, data: { outcome: types_1.SCAN_OUTCOMES.FORBIDDEN, error } };
|
|
73
|
+
}
|
|
74
|
+
function conflict(error) {
|
|
75
|
+
return { status: 200, data: { outcome: types_1.SCAN_OUTCOMES.CONFLICT, error } };
|
|
76
|
+
}
|
|
77
|
+
function notPrimed(ctx) {
|
|
78
|
+
return {
|
|
79
|
+
status: 200,
|
|
80
|
+
data: {
|
|
81
|
+
outcome: types_1.SCAN_OUTCOMES.NOT_PRIMED,
|
|
82
|
+
notPrimed: ctx.rule.notPrimed,
|
|
83
|
+
error: 'an acting identity is required — scan your badge',
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ScanExecuteRequest, type ScanExecuteResponse } from '../../types';
|
|
2
2
|
import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
3
|
+
export type { StepContext } from './context';
|
|
3
4
|
/**
|
|
4
5
|
* Execute a raw scan code: parse → load the rule → walk its steps in order.
|
|
5
6
|
* The first step whose condition matches performs its verb and answers; a
|