@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
|
@@ -7,6 +7,7 @@ const metadata_1 = require("./metadata");
|
|
|
7
7
|
const single_1 = require("./single");
|
|
8
8
|
const resolve_1 = require("./resolve");
|
|
9
9
|
const facets_1 = require("./facets");
|
|
10
|
+
const analytics_1 = require("./analytics");
|
|
10
11
|
const router = (0, express_1.Router)();
|
|
11
12
|
// Registration order matters: literal paths before parameterized /:id routes.
|
|
12
13
|
// GET /, /available, /types, /stats
|
|
@@ -18,6 +19,8 @@ const router = (0, express_1.Router)();
|
|
|
18
19
|
(0, metadata_1.registerMetadataRoutes)(router);
|
|
19
20
|
// POST /search-by-facets, /claim-groups, /claim-by-facets
|
|
20
21
|
(0, facets_1.registerFacetRoutes)(router);
|
|
22
|
+
// POST /aggregate-by-facets, /timeline-by-facet
|
|
23
|
+
(0, analytics_1.registerAnalyticsRoutes)(router);
|
|
21
24
|
// PATCH /:id/escalate, GET /by-workflow/:workflowId,
|
|
22
25
|
// GET /:id, POST /:id/claim, POST /:id/release
|
|
23
26
|
(0, single_1.registerSingleRoutes)(router);
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.registerResolveRoutes = registerResolveRoutes;
|
|
37
37
|
const api = __importStar(require("../../api/escalations"));
|
|
38
|
+
const acting_1 = require("./acting");
|
|
38
39
|
function registerResolveRoutes(router) {
|
|
39
40
|
/**
|
|
40
41
|
* POST /api/escalations/resolve-by-signal-key
|
|
@@ -92,7 +93,13 @@ function registerResolveRoutes(router) {
|
|
|
92
93
|
* Body: { resolverPayload: Record<string, any>, metadata?: Record<string, any> }
|
|
93
94
|
*/
|
|
94
95
|
router.post('/:id/resolve', async (req, res) => {
|
|
95
|
-
|
|
96
|
+
// The actor is the token user — or the badged person when an
|
|
97
|
+
// X-LT-Acting-Token grant rides the request (station continuity: the
|
|
98
|
+
// person who claimed by badge submits by badge).
|
|
99
|
+
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
100
|
+
if (!auth)
|
|
101
|
+
return;
|
|
102
|
+
const result = await api.resolveEscalation({ id: req.params.id, resolverPayload: req.body?.resolverPayload, metadata: req.body?.metadata }, auth);
|
|
96
103
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
97
104
|
});
|
|
98
105
|
}
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.registerSingleRoutes = registerSingleRoutes;
|
|
37
37
|
const api = __importStar(require("../../api/escalations"));
|
|
38
|
+
const acting_1 = require("./acting");
|
|
38
39
|
function registerSingleRoutes(router) {
|
|
39
40
|
/**
|
|
40
41
|
* PATCH /api/escalations/:id/escalate
|
|
@@ -67,20 +68,28 @@ function registerSingleRoutes(router) {
|
|
|
67
68
|
});
|
|
68
69
|
/**
|
|
69
70
|
* POST /api/escalations/:id/claim
|
|
70
|
-
* Claim an escalation.
|
|
71
|
+
* Claim an escalation. The actor is the auth token's user — or the badged
|
|
72
|
+
* person when an X-LT-Acting-Token grant rides the request.
|
|
71
73
|
* Body: { durationMinutes?: number }
|
|
72
74
|
*/
|
|
73
75
|
router.post('/:id/claim', async (req, res) => {
|
|
74
|
-
const
|
|
76
|
+
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
77
|
+
if (!auth)
|
|
78
|
+
return;
|
|
79
|
+
const result = await api.claimEscalation({ id: req.params.id, durationMinutes: req.body?.durationMinutes, provisionIfAbsent: req.body?.provisionIfAbsent }, auth);
|
|
75
80
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
76
81
|
});
|
|
77
82
|
/**
|
|
78
83
|
* POST /api/escalations/:id/release
|
|
79
84
|
* Release a claimed escalation back to the available pool.
|
|
80
|
-
* Only the assigned user
|
|
85
|
+
* Only the assigned actor (token user, or the badged person when an
|
|
86
|
+
* X-LT-Acting-Token grant rides the request) may release their own claim.
|
|
81
87
|
*/
|
|
82
88
|
router.post('/:id/release', async (req, res) => {
|
|
83
|
-
const
|
|
89
|
+
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
90
|
+
if (!auth)
|
|
91
|
+
return;
|
|
92
|
+
const result = await api.releaseEscalation({ id: req.params.id }, auth);
|
|
84
93
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
85
94
|
});
|
|
86
95
|
/**
|
package/build/routes/roles.js
CHANGED
|
@@ -95,7 +95,7 @@ router.delete('/escalation-chains', auth_1.requireRoleManager, async (req, res)
|
|
|
95
95
|
/**
|
|
96
96
|
* PATCH /api/roles/:role
|
|
97
97
|
* Update role metadata. Requires admin.
|
|
98
|
-
* Body: { title?, description?, form_schema?, metadata_schema?, properties?, ops_visible?, parent_role?, sla_minutes?, target_per_hour?, worker_count?, priority_threshold_minutes?, priority_facet? }
|
|
98
|
+
* Body: { title?, description?, form_schema?, metadata_schema?, properties?, ops_visible?, parent_role?, sla_minutes?, target_per_hour?, worker_count?, priority_threshold_minutes?, priority_facet?, entity_facet?, entity_state_source? }
|
|
99
99
|
*/
|
|
100
100
|
router.patch('/:role', auth_1.requireRoleManager, async (req, res) => {
|
|
101
101
|
// URL is the resource identity — a `role` key in the body must not redirect
|
|
@@ -40,11 +40,33 @@ const router = (0, express_1.Router)();
|
|
|
40
40
|
// ── Execute ───────────────────────────────────────────────────────────────
|
|
41
41
|
/**
|
|
42
42
|
* POST /api/scan-codes/execute
|
|
43
|
-
* Execute a raw scan code (from any input source) as the calling
|
|
43
|
+
* Execute a raw scan code (from any input source). Verbs run as the calling
|
|
44
|
+
* user, or as the badged person when an acting-identity grant rides along.
|
|
44
45
|
* Every terminal state is a structured 200 outcome.
|
|
45
46
|
*/
|
|
46
47
|
router.post('/execute', async (req, res) => {
|
|
47
|
-
const result = await api.executeScanCode({
|
|
48
|
+
const result = await api.executeScanCode({
|
|
49
|
+
code: req.body.code,
|
|
50
|
+
actingToken: req.body.actingToken,
|
|
51
|
+
previousActingToken: req.body.previousActingToken,
|
|
52
|
+
}, req.auth);
|
|
53
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* POST /api/scan-codes/execute-choice
|
|
57
|
+
* Execute one choice presented by a PRESENT step. The body is a pointer
|
|
58
|
+
* (scheme/category/step/choice + escalationId); the server re-validates
|
|
59
|
+
* config, row state, identity, and RBAC before the verb runs.
|
|
60
|
+
*/
|
|
61
|
+
router.post('/execute-choice', async (req, res) => {
|
|
62
|
+
const result = await api.executeScanChoice({
|
|
63
|
+
schemeVersion: req.body.schemeVersion,
|
|
64
|
+
category: req.body.category,
|
|
65
|
+
stepIndex: req.body.stepIndex,
|
|
66
|
+
choiceIndex: req.body.choiceIndex,
|
|
67
|
+
escalationId: req.body.escalationId,
|
|
68
|
+
actingToken: req.body.actingToken,
|
|
69
|
+
}, req.auth);
|
|
48
70
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
49
71
|
});
|
|
50
72
|
// ── Scheme CRUD (admin, engineer, superadmin) ─────────────────────────────
|
|
@@ -77,6 +99,9 @@ router.put('/schemes/:version', auth_1.requireRoleManager, async (req, res) => {
|
|
|
77
99
|
encoding: req.body.encoding,
|
|
78
100
|
delimiter: req.body.delimiter,
|
|
79
101
|
target_length: req.body.target_length,
|
|
102
|
+
kind: req.body.kind,
|
|
103
|
+
grant_ttl_seconds: req.body.grant_ttl_seconds,
|
|
104
|
+
grant_max_uses: req.body.grant_max_uses,
|
|
80
105
|
enabled: req.body.enabled,
|
|
81
106
|
});
|
|
82
107
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
@@ -120,6 +145,7 @@ router.put('/schemes/:version/actions/:category', auth_1.requireRoleManager, asy
|
|
|
120
145
|
name: req.body.name,
|
|
121
146
|
steps: req.body.steps,
|
|
122
147
|
fallback: req.body.fallback,
|
|
148
|
+
notPrimed: req.body.notPrimed,
|
|
123
149
|
enabled: req.body.enabled,
|
|
124
150
|
});
|
|
125
151
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
@@ -162,6 +162,20 @@ async function ensureSideQuestRoles() {
|
|
|
162
162
|
await api('PATCH', '/api/roles/ship', { upstream_roles: [...upstreams, 'inserting'] });
|
|
163
163
|
}
|
|
164
164
|
console.log(`[${ts()}] Side-quest roles ready (ordering → inserting ⇒ ship)`);
|
|
165
|
+
// Declare each station's entity: the order is what moves through every one
|
|
166
|
+
// of these roles, so entity_facet = 'order_id' unlocks distinct-order
|
|
167
|
+
// counts, per-order dwell, and order timelines on the Pace Board. Set only
|
|
168
|
+
// where unset — an operator-configured entity is never overwritten.
|
|
169
|
+
let declared = 0;
|
|
170
|
+
for (const role of ALL_ROLES) {
|
|
171
|
+
const detail = (details?.roles ?? []).find((r) => r.role === role);
|
|
172
|
+
if (!detail || detail.entity_facet)
|
|
173
|
+
continue;
|
|
174
|
+
await api('PATCH', `/api/roles/${role}`, { entity_facet: 'order_id' }).catch(() => { });
|
|
175
|
+
declared++;
|
|
176
|
+
}
|
|
177
|
+
if (declared > 0)
|
|
178
|
+
console.log(`[${ts()}] Entity declared on ${declared} role(s): order_id`);
|
|
165
179
|
}
|
|
166
180
|
// ── Side-quest escalations (standalone rows — no workflow behind them) ────────
|
|
167
181
|
async function createSideEscalation(role, workflowId, orderId, runId, description, authorizedAt) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* printer-cycle — drive the seeded printer fleet through its states live.
|
|
3
|
+
*
|
|
4
|
+
* The flagship entity-analytics demo (examples/seed-fleet-sim.ts) seeds six
|
|
5
|
+
* printers with backdated history and one open interval each. This driver
|
|
6
|
+
* keeps the fleet moving: each printer dwells in its current state, then the
|
|
7
|
+
* open escalation resolves and the next state's escalation is created after a
|
|
8
|
+
* short untracked settle gap — exactly the authoring contract a real workflow
|
|
9
|
+
* follows with condition(). Watch /operations: the state band, slice-by, and
|
|
10
|
+
* per-printer timelines move within seconds of every transition.
|
|
11
|
+
*
|
|
12
|
+
* State machine per printer: idle → printing → harvest → (service |) idle …
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* npx ts-node scripts/printer-cycle.ts
|
|
16
|
+
* DWELL_SCALE=0.2 npx ts-node scripts/printer-cycle.ts (5× faster)
|
|
17
|
+
*
|
|
18
|
+
* Env vars:
|
|
19
|
+
* DWELL_SCALE — multiply every dwell/gap (default 1; smaller = faster demo)
|
|
20
|
+
* CYCLES — stop after each printer completes this many transitions
|
|
21
|
+
* (default: run until interrupted)
|
|
22
|
+
* POLL_MS — poll interval ms (default 1000)
|
|
23
|
+
* BASE_URL — server URL (default http://localhost:3000)
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* printer-cycle — drive the seeded printer fleet through its states live.
|
|
4
|
+
*
|
|
5
|
+
* The flagship entity-analytics demo (examples/seed-fleet-sim.ts) seeds six
|
|
6
|
+
* printers with backdated history and one open interval each. This driver
|
|
7
|
+
* keeps the fleet moving: each printer dwells in its current state, then the
|
|
8
|
+
* open escalation resolves and the next state's escalation is created after a
|
|
9
|
+
* short untracked settle gap — exactly the authoring contract a real workflow
|
|
10
|
+
* follows with condition(). Watch /operations: the state band, slice-by, and
|
|
11
|
+
* per-printer timelines move within seconds of every transition.
|
|
12
|
+
*
|
|
13
|
+
* State machine per printer: idle → printing → harvest → (service |) idle …
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* npx ts-node scripts/printer-cycle.ts
|
|
17
|
+
* DWELL_SCALE=0.2 npx ts-node scripts/printer-cycle.ts (5× faster)
|
|
18
|
+
*
|
|
19
|
+
* Env vars:
|
|
20
|
+
* DWELL_SCALE — multiply every dwell/gap (default 1; smaller = faster demo)
|
|
21
|
+
* CYCLES — stop after each printer completes this many transitions
|
|
22
|
+
* (default: run until interrupted)
|
|
23
|
+
* POLL_MS — poll interval ms (default 1000)
|
|
24
|
+
* BASE_URL — server URL (default http://localhost:3000)
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
try {
|
|
28
|
+
require('dotenv/config');
|
|
29
|
+
}
|
|
30
|
+
catch { }
|
|
31
|
+
const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
|
|
32
|
+
const DWELL_SCALE = parseFloat(process.env.DWELL_SCALE || '1');
|
|
33
|
+
const CYCLES = parseInt(process.env.CYCLES || '0', 10);
|
|
34
|
+
const POLL_MS = parseInt(process.env.POLL_MS || '1000', 10);
|
|
35
|
+
const FLEET_ROLE = 'printer-fleet';
|
|
36
|
+
const HARVEST_ROLE = 'printer-harvest';
|
|
37
|
+
const SERVICE_ROLE = 'printer-service';
|
|
38
|
+
const ROLES = [FLEET_ROLE, HARVEST_ROLE, SERVICE_ROLE];
|
|
39
|
+
const ENTITY_FACET = 'serialNumber';
|
|
40
|
+
/** Seconds a printer dwells in each state (before DWELL_SCALE and jitter). */
|
|
41
|
+
const DWELL_S = { idle: 45, printing: 120, harvest: 20, service: 60 };
|
|
42
|
+
const GAP_S = 5; // untracked settle time between queues
|
|
43
|
+
const STATES = {
|
|
44
|
+
idle: { role: FLEET_ROLE, subtype: 'idle' },
|
|
45
|
+
printing: { role: FLEET_ROLE, subtype: 'printing' },
|
|
46
|
+
harvest: { role: HARVEST_ROLE, subtype: 'harvest' },
|
|
47
|
+
service: { role: SERVICE_ROLE, subtype: 'service' },
|
|
48
|
+
};
|
|
49
|
+
let token = '';
|
|
50
|
+
let transitions = 0;
|
|
51
|
+
function ts() { return new Date().toISOString().slice(11, 19); }
|
|
52
|
+
function sleep(ms) { return new Promise((r) => setTimeout(r, ms)); }
|
|
53
|
+
function ageSeconds(iso) { return (Date.now() - new Date(iso).getTime()) / 1000; }
|
|
54
|
+
/** Deterministic per-row jitter in [0, 1) — FNV-1a of the escalation id. */
|
|
55
|
+
function jitter(id, salt) {
|
|
56
|
+
let h = 2166136261;
|
|
57
|
+
for (const c of salt + id) {
|
|
58
|
+
h ^= c.charCodeAt(0);
|
|
59
|
+
h = Math.imul(h, 16777619);
|
|
60
|
+
}
|
|
61
|
+
return ((h >>> 0) % 1000) / 1000;
|
|
62
|
+
}
|
|
63
|
+
async function api(method, path, body) {
|
|
64
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
65
|
+
method,
|
|
66
|
+
headers: {
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
69
|
+
},
|
|
70
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
71
|
+
});
|
|
72
|
+
const data = await res.json().catch(() => ({}));
|
|
73
|
+
if (!res.ok)
|
|
74
|
+
throw new Error(`${method} ${path} → ${res.status}: ${JSON.stringify(data)}`);
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
async function login() {
|
|
78
|
+
const auth = await api('POST', '/api/auth/login', { username: 'superadmin', password: 'l0ngt@1l' });
|
|
79
|
+
token = auth.token;
|
|
80
|
+
if (!token) {
|
|
81
|
+
console.error('[auth] Login failed');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
console.log(`[${ts()}] Logged in`);
|
|
85
|
+
}
|
|
86
|
+
/** Self-heal the entity dials: declare where unset, never overwrite (S2). */
|
|
87
|
+
async function ensureEntityDials() {
|
|
88
|
+
const details = await api('GET', '/api/roles/details').catch(() => ({ roles: [] }));
|
|
89
|
+
const byRole = new Map((details?.roles ?? []).map((r) => [r.role, r]));
|
|
90
|
+
for (const role of ROLES) {
|
|
91
|
+
const row = byRole.get(role);
|
|
92
|
+
if (!row) {
|
|
93
|
+
console.error(`[${ts()}] role ${role} is missing — run the seeded install first (docker compose up with examples)`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
if (row.entity_facet == null) {
|
|
97
|
+
await api('PATCH', `/api/roles/${role}`, {
|
|
98
|
+
entity_facet: ENTITY_FACET,
|
|
99
|
+
entity_state_source: role === FLEET_ROLE ? 'subtype' : 'role',
|
|
100
|
+
}).catch(() => { });
|
|
101
|
+
console.log(`[${ts()}] declared entity dials on ${role}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The state a printer enters after `current` — service follows ~⅓ of harvests. */
|
|
106
|
+
function nextState(current, rowId) {
|
|
107
|
+
if (current === 'idle')
|
|
108
|
+
return 'printing';
|
|
109
|
+
if (current === 'printing')
|
|
110
|
+
return 'harvest';
|
|
111
|
+
if (current === 'harvest')
|
|
112
|
+
return jitter(rowId, 'svc') < 0.33 ? 'service' : 'idle';
|
|
113
|
+
return 'idle'; // service → back to the floor
|
|
114
|
+
}
|
|
115
|
+
async function transition(row) {
|
|
116
|
+
const serial = row.metadata?.[ENTITY_FACET];
|
|
117
|
+
const current = row.role === FLEET_ROLE ? row.subtype : row.role === HARVEST_ROLE ? 'harvest' : 'service';
|
|
118
|
+
const next = nextState(current, row.id);
|
|
119
|
+
await api('POST', `/api/escalations/${row.id}/resolve`, {
|
|
120
|
+
resolverPayload: { outcome: current, driver: 'printer-cycle' },
|
|
121
|
+
});
|
|
122
|
+
await sleep(GAP_S * DWELL_SCALE * 1000 * (0.5 + jitter(row.id, 'gap')));
|
|
123
|
+
const def = STATES[next];
|
|
124
|
+
await api('POST', '/api/escalations', {
|
|
125
|
+
type: 'fleet',
|
|
126
|
+
subtype: def.subtype,
|
|
127
|
+
role: def.role,
|
|
128
|
+
description: `${serial} — ${next}`,
|
|
129
|
+
priority: 3,
|
|
130
|
+
envelope: JSON.stringify({ source: 'printer-cycle' }),
|
|
131
|
+
metadata: { ...row.metadata },
|
|
132
|
+
});
|
|
133
|
+
transitions++;
|
|
134
|
+
console.log(`[${ts()}] ${serial}: ${current} → ${next}`);
|
|
135
|
+
}
|
|
136
|
+
/** Every live printer interval across the three queues. */
|
|
137
|
+
async function liveRows() {
|
|
138
|
+
const params = new URLSearchParams({
|
|
139
|
+
status: 'pending',
|
|
140
|
+
roles: JSON.stringify(ROLES),
|
|
141
|
+
exists: JSON.stringify([ENTITY_FACET]),
|
|
142
|
+
limit: '200',
|
|
143
|
+
});
|
|
144
|
+
const data = await api('GET', `/api/escalations?${params}`);
|
|
145
|
+
return data.escalations ?? [];
|
|
146
|
+
}
|
|
147
|
+
async function main() {
|
|
148
|
+
console.log(`[${ts()}] printer-cycle starting (scale ${DWELL_SCALE}, ${CYCLES || '∞'} transitions/printer)`);
|
|
149
|
+
await login();
|
|
150
|
+
await ensureEntityDials();
|
|
151
|
+
const perPrinterCap = CYCLES > 0 ? CYCLES * 6 : Infinity; // 6 seeded printers
|
|
152
|
+
while (transitions < perPrinterCap) {
|
|
153
|
+
const rows = await liveRows();
|
|
154
|
+
if (rows.length === 0) {
|
|
155
|
+
console.log(`[${ts()}] no live printer intervals — seed the fleet first`);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
for (const row of rows) {
|
|
159
|
+
const state = row.role === FLEET_ROLE ? row.subtype : row.role === HARVEST_ROLE ? 'harvest' : 'service';
|
|
160
|
+
const dwell = (DWELL_S[state] ?? 30) * DWELL_SCALE * (0.6 + 0.8 * jitter(row.id, 'dwell'));
|
|
161
|
+
if (ageSeconds(row.created_at) >= dwell) {
|
|
162
|
+
await transition(row).catch((err) => console.error(`[${ts()}] transition failed: ${String(err.message).slice(0, 100)}`));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
await sleep(POLL_MS);
|
|
166
|
+
}
|
|
167
|
+
console.log(`[${ts()}] done — ${transitions} transitions`);
|
|
168
|
+
}
|
|
169
|
+
main().catch((err) => { console.error(err); process.exit(1); });
|
|
@@ -111,12 +111,17 @@ async function login() {
|
|
|
111
111
|
*
|
|
112
112
|
* Topology: print-jobs ─▶ printer-fleet (production line), with print-servicer
|
|
113
113
|
* a side-quest root merging into the fleet.
|
|
114
|
+
*
|
|
115
|
+
* The three printer roles share entity_facet 'serialNumber' (every twin row
|
|
116
|
+
* carries it) — together with the flagship printer roles they form the
|
|
117
|
+
* printer's SYSTEM, so onboarding and servicing intervals join the machine's
|
|
118
|
+
* timeline and state band.
|
|
114
119
|
*/
|
|
115
120
|
const TWIN_ROLE_CONFIG = [
|
|
116
121
|
{ role: 'print-jobs', title: 'Print Jobs', parent_role: null, sla_minutes: 5, target_per_hour: 30, priority_threshold_minutes: 5, description: 'Order demand — one print-job escalation per unit, claimed as a set.' },
|
|
117
|
-
{ role: 'printer-fleet', title: 'Printer Fleet', parent_role: 'print-jobs', sla_minutes: 5, target_per_hour: 30, priority_threshold_minutes: 5, description: 'Twin availability adverts and in-flight print rows — the machines at work.', upstream_roles: ['print-onboarder', 'print-servicer'] },
|
|
118
|
-
{ role: 'print-onboarder', title: 'Print Onboarder', parent_role: null, sla_minutes: 15, target_per_hour: 5, priority_threshold_minutes: 15, description: 'Register + bind a newly unboxed machine.' },
|
|
119
|
-
{ role: 'print-servicer', title: 'Print Servicer', parent_role: null, sla_minutes: 10, target_per_hour: 10, priority_threshold_minutes: 10, description: 'Reload filament, inspect failures, restore offline machines.' },
|
|
122
|
+
{ role: 'printer-fleet', title: 'Printer Fleet', parent_role: 'print-jobs', sla_minutes: 5, target_per_hour: 30, priority_threshold_minutes: 5, description: 'Twin availability adverts and in-flight print rows — the machines at work.', upstream_roles: ['print-onboarder', 'print-servicer'], entity_facet: 'serialNumber', entity_state_source: 'subtype' },
|
|
123
|
+
{ role: 'print-onboarder', title: 'Print Onboarder', parent_role: null, sla_minutes: 15, target_per_hour: 5, priority_threshold_minutes: 15, description: 'Register + bind a newly unboxed machine.', entity_facet: 'serialNumber', entity_state_source: 'role' },
|
|
124
|
+
{ role: 'print-servicer', title: 'Print Servicer', parent_role: null, sla_minutes: 10, target_per_hour: 10, priority_threshold_minutes: 10, description: 'Reload filament, inspect failures, restore offline machines.', entity_facet: 'serialNumber', entity_state_source: 'role' },
|
|
120
125
|
];
|
|
121
126
|
async function ensureTwinRoles() {
|
|
122
127
|
const details = await api('GET', '/api/roles/details').catch(() => ({ roles: [] }));
|
|
@@ -129,8 +134,17 @@ async function ensureTwinRoles() {
|
|
|
129
134
|
let applied = 0;
|
|
130
135
|
for (const cfg of TWIN_ROLE_CONFIG) {
|
|
131
136
|
const row = configured.get(cfg.role);
|
|
132
|
-
if (row?.title)
|
|
133
|
-
|
|
137
|
+
if (row?.title) {
|
|
138
|
+
// Already configured — respect admin tuning, but self-heal the entity
|
|
139
|
+
// dials where the role predates them (set only when unset).
|
|
140
|
+
if ('entity_facet' in cfg && row.entity_facet == null) {
|
|
141
|
+
await api('PATCH', `/api/roles/${cfg.role}`, {
|
|
142
|
+
entity_facet: cfg.entity_facet,
|
|
143
|
+
entity_state_source: cfg.entity_state_source,
|
|
144
|
+
}).catch(() => { });
|
|
145
|
+
}
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
134
148
|
const { role, ...body } = cfg;
|
|
135
149
|
await api('PATCH', `/api/roles/${role}`, { ...body, ops_visible: true }).then(() => { applied++; }).catch((err) => {
|
|
136
150
|
console.warn(`[${ts()}] ⚠ role ${role}: ${String(err.message).slice(0, 80)}`);
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -227,6 +227,8 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
227
227
|
durationMinutes?: number;
|
|
228
228
|
allOrNone?: boolean;
|
|
229
229
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
230
|
+
aggregateByFacets: (input: import("..").AggregateByFacetsInput, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
231
|
+
timelineByFacet: (input: import("..").TimelineByFacetInput, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
230
232
|
};
|
|
231
233
|
workflows: {
|
|
232
234
|
invoke: (input: {
|
package/build/sdk/index.js
CHANGED
|
@@ -145,6 +145,9 @@ function createClient(options = {}) {
|
|
|
145
145
|
searchByFacets: bindAuth(escalationsApi.searchByFacets, auth),
|
|
146
146
|
claimGroups: bindAuth(escalationsApi.claimGroups, auth),
|
|
147
147
|
claimByFacets: bindAuth(escalationsApi.claimByFacets, auth),
|
|
148
|
+
// Analytics surface (grouped membership/dwell + per-entity timeline), read_all-gated.
|
|
149
|
+
aggregateByFacets: bindAuth(escalationsApi.aggregateByFacets, auth),
|
|
150
|
+
timelineByFacet: bindAuth(escalationsApi.timelineByFacet, auth),
|
|
148
151
|
},
|
|
149
152
|
// ── Workflows ──────────────────────────────────────────────────────────
|
|
150
153
|
workflows: {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AggregateByFacetsInput, GroupableColumn, TimelineByFacetInput } from '../../types';
|
|
2
|
+
export { AnalyticsInputError } from './aggregate-validate';
|
|
3
|
+
export interface BuiltAggregateQuery {
|
|
4
|
+
sql: string;
|
|
5
|
+
params: unknown[];
|
|
6
|
+
/** Groups per page; the SQL fetches pageLimit + 1 rows to detect overflow. */
|
|
7
|
+
pageLimit: number;
|
|
8
|
+
columns: GroupableColumn[];
|
|
9
|
+
facets: string[];
|
|
10
|
+
/** true when grouped by the derived state label (groupBy.state). */
|
|
11
|
+
stateGrouped: boolean;
|
|
12
|
+
measureKind: 'membership' | 'dwell';
|
|
13
|
+
/** true = the anchor touches now (short cache); false = fully past (immutable). */
|
|
14
|
+
nowAnchored: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Per-role state naming, from lt_roles.entity_state_source. */
|
|
17
|
+
export type StateSources = Record<string, 'role' | 'subtype'>;
|
|
18
|
+
export interface BuiltTimelineQuery {
|
|
19
|
+
sql: string;
|
|
20
|
+
params: unknown[];
|
|
21
|
+
pageLimit: number;
|
|
22
|
+
columns: GroupableColumn[];
|
|
23
|
+
facets: string[];
|
|
24
|
+
nowAnchored: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the grouped aggregate (membership or dwell) as one parameterized
|
|
28
|
+
* query. `query.entity` must be RESOLVED by the caller before building
|
|
29
|
+
* (aggregates.ts turns it into roles + opts.stateSources); the builder
|
|
30
|
+
* rejects an unresolved entity so it can never be silently ignored.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildAggregateQuery(input: AggregateByFacetsInput, opts?: {
|
|
33
|
+
stateSources?: StateSources;
|
|
34
|
+
}): BuiltAggregateQuery;
|
|
35
|
+
/** Build the single-entity interval sequence, created_at-ordered, gaps preserved. */
|
|
36
|
+
export declare function buildTimelineQuery(input: TimelineByFacetInput): BuiltTimelineQuery;
|