@hotmeshio/long-tail 0.23.1 → 0.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +4 -1
- package/build/api/escalations/list.d.ts +5 -0
- package/build/api/escalations/list.js +19 -5
- package/build/api/escalations/related.d.ts +18 -0
- package/build/api/escalations/related.js +205 -0
- package/build/api/roles.js +4 -0
- package/build/api/scan-codes/present.js +5 -1
- package/build/api/settings.d.ts +1 -1
- package/build/api/settings.js +3 -1
- package/build/modules/display.d.ts +15 -0
- package/build/modules/display.js +27 -0
- package/build/routes/escalations/index.js +3 -0
- package/build/routes/escalations/list.js +2 -0
- package/build/routes/escalations/related.d.ts +7 -0
- package/build/routes/escalations/related.js +60 -0
- package/build/scripts/consolidation-sim.d.ts +25 -0
- package/build/scripts/consolidation-sim.js +141 -0
- package/build/sdk/index.d.ts +12 -0
- package/build/sdk/index.js +2 -0
- package/build/services/escalation/grouped-list.d.ts +19 -0
- package/build/services/escalation/grouped-list.js +54 -0
- package/build/services/escalation/index.d.ts +4 -0
- package/build/services/escalation/index.js +9 -1
- package/build/services/escalation/queries.d.ts +17 -13
- package/build/services/escalation/queries.js +31 -40
- package/build/services/escalation/read-scope-sql.d.ts +13 -0
- package/build/services/escalation/read-scope-sql.js +19 -0
- package/build/services/escalation/related.d.ts +58 -0
- package/build/services/escalation/related.js +196 -0
- package/build/services/role/index.js +6 -0
- package/build/services/role/seed.js +4 -0
- package/build/services/scan-code/validate-facts.d.ts +1 -1
- package/build/services/scan-code/validate-facts.js +12 -1
- package/build/shared/form-validation/x-lt-scan.d.ts +8 -0
- package/build/shared/form-validation/x-lt-scan.js +20 -1
- package/build/shared/list-schema/index.d.ts +3 -0
- package/build/shared/list-schema/index.js +27 -0
- package/build/shared/list-schema/template.d.ts +14 -0
- package/build/shared/list-schema/template.js +85 -0
- package/build/shared/list-schema/types.d.ts +154 -0
- package/build/shared/list-schema/types.js +55 -0
- package/build/shared/list-schema/validate.d.ts +12 -0
- package/build/shared/list-schema/validate.js +204 -0
- package/build/shared/roles/segment.d.ts +22 -0
- package/build/shared/roles/segment.js +42 -0
- package/build/start/adapters.js +2 -0
- package/build/system/mcp-servers/admin/users.js +8 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.js +2 -1
- package/build/types/scan-code/constants.d.ts +7 -0
- package/build/types/scan-code/constants.js +7 -1
- package/build/types/scan-code/response.d.ts +3 -2
- package/build/types/scan-code/rule.d.ts +6 -1
- package/build/types/startup.d.ts +8 -0
- package/dashboard/dist/assets/{AdminDashboard-DKrqLGjn.js → AdminDashboard-BPWsgMfZ.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DKrqLGjn.js.map → AdminDashboard-BPWsgMfZ.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BoQhRW6U.js → AgentConfigPage-De9imyo5.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-BoQhRW6U.js.map → AgentConfigPage-De9imyo5.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DZhzuZmO.js → AgentDetailPage-B6o96Y5G.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-DZhzuZmO.js.map → AgentDetailPage-B6o96Y5G.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-5MynmbWX.js → AgentsPage-DMEmiK_W.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-5MynmbWX.js.map → AgentsPage-DMEmiK_W.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DeYMngwE.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-DeYMngwE.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-C3LR6Sqy.js → BotPicker-DDmpgGHZ.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-C3LR6Sqy.js.map → BotPicker-DDmpgGHZ.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-COjoOIIH.js → BulkAssignModal-BqlklomG.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-COjoOIIH.js.map → BulkAssignModal-BqlklomG.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-DOtjDTbK.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-DKxLvOfB.js.map → CapabilitiesPage-DOtjDTbK.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-Cz5sRx-r.js → CollapsibleSection-CLr8LP0V.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-Cz5sRx-r.js.map → CollapsibleSection-CLr8LP0V.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-Beq1vQtY.js → ConfirmDeleteModal-DW4DrPur.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-Beq1vQtY.js.map → ConfirmDeleteModal-DW4DrPur.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-DxX72PwV.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-DxX72PwV.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-DhiHiPsG.js → CredentialsPage-CObc9Rs5.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-DhiHiPsG.js.map → CredentialsPage-CObc9Rs5.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-C9SkawB-.js → CronLabel-Bb8GoNY5.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-C9SkawB-.js.map → CronLabel-Bb8GoNY5.js.map} +1 -1
- package/dashboard/dist/assets/DataTable-FjFhx0SE.js +2 -0
- package/dashboard/dist/assets/DataTable-FjFhx0SE.js.map +1 -0
- package/dashboard/dist/assets/{ElapsedCell-BeK1SUDK.js → ElapsedCell-CmGhVlYl.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BeK1SUDK.js.map → ElapsedCell-CmGhVlYl.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-BThdefKj.js → EntityTimelinePanel-B4Jwy1w3.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-BThdefKj.js.map → EntityTimelinePanel-B4Jwy1w3.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-DlDIYb-p.js → EscalationListSchemaPage-CZZbZ4Aa.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-DlDIYb-p.js.map → EscalationListSchemaPage-CZZbZ4Aa.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-CQt-Embr.js → EscalationSchemaPage-D0ko59_S.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-CQt-Embr.js.map → EscalationSchemaPage-D0ko59_S.js.map} +1 -1
- package/dashboard/dist/assets/EscalationTimeline-BcnJEKFD.js +2 -0
- package/dashboard/dist/assets/EscalationTimeline-BcnJEKFD.js.map +1 -0
- package/dashboard/dist/assets/{EscalationTitleSelect-Dewrv8wX.js → EscalationTitleSelect-P0q5sck4.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-Dewrv8wX.js.map → EscalationTitleSelect-P0q5sck4.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BzH-Y-5x.js → EscalationsOverview-BLPmh4AF.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BzH-Y-5x.js.map → EscalationsOverview-BLPmh4AF.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-C97m6IZv.js → EventTable-gBzi5tIS.js} +2 -2
- package/dashboard/dist/assets/{EventTable-C97m6IZv.js.map → EventTable-gBzi5tIS.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-D-6xVHIw.js → FilterBar-BulSsWb2.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-D-6xVHIw.js.map → FilterBar-BulSsWb2.js.map} +1 -1
- package/dashboard/dist/assets/FormattedValue-BMHRrvrL.js +2 -0
- package/dashboard/dist/assets/FormattedValue-BMHRrvrL.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-Bwi8EF9Y.js → GraphInvokePage--997yNRr.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-Bwi8EF9Y.js.map → GraphInvokePage--997yNRr.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-Z_Q03C0z.js → HomePage-CwXFz--v.js} +2 -2
- package/dashboard/dist/assets/{HomePage-Z_Q03C0z.js.map → HomePage-CwXFz--v.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-_jWTw5no.js → ListToolbar-Df4qZryJ.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-_jWTw5no.js.map → ListToolbar-Df4qZryJ.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CjqTuP0N.js → McpOverview-DrogIAKJ.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CjqTuP0N.js.map → McpOverview-DrogIAKJ.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-leCsje1U.js → McpQueryDetailPage-CJmvCAE6.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-leCsje1U.js.map → McpQueryDetailPage-CJmvCAE6.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-C-PyXYX4.js → McpQueryPage-lygo4Yq0.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-C-PyXYX4.js.map → McpQueryPage-lygo4Yq0.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-JDrr3uUQ.js → McpRunDetailPage-hvns2sCm.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-JDrr3uUQ.js.map → McpRunDetailPage-hvns2sCm.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-DERXQLgZ.js → McpRunsPage-C2_7spTX.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-DERXQLgZ.js.map → McpRunsPage-C2_7spTX.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-B2DA7n9m.js → OperationsPage-BlK8WlsY.js} +3 -3
- package/dashboard/dist/assets/OperationsPage-BlK8WlsY.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-BeWBiMGX.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-BeWBiMGX.js.map +1 -0
- package/dashboard/dist/assets/{PersonaDetailPage-ChXwJ6u5.js → PersonaDetailPage-CNHpsX_i.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-ChXwJ6u5.js.map → PersonaDetailPage-CNHpsX_i.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-BFFxncSE.js → PersonasPage-ChASEZRg.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-BFFxncSE.js.map → PersonasPage-ChASEZRg.js.map} +1 -1
- package/dashboard/dist/assets/PortalPage-D5Lk-PKF.js +2 -0
- package/dashboard/dist/assets/PortalPage-D5Lk-PKF.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-D7EYwW-j.js → ProcessDetailPage-DNgCIwRl.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-D7EYwW-j.js.map → ProcessDetailPage-DNgCIwRl.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CakYRtnE.js → ProcessesListPage-pRjWuWlH.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CakYRtnE.js.map → ProcessesListPage-pRjWuWlH.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-CKIOAGtY.js +8 -0
- package/dashboard/dist/assets/ResolverForm-CKIOAGtY.js.map +1 -0
- package/dashboard/dist/assets/{RoleDetailPage-CKbGwezP.js → RoleDetailPage-Bh_UcfYY.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-CKbGwezP.js.map → RoleDetailPage-Bh_UcfYY.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-Czu7Zku4.js → RolesPage-CK17N7zz.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-Czu7Zku4.js.map → RolesPage-CK17N7zz.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-6BLScYTX.js → RunAsSelector-BEKUP0p2.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-6BLScYTX.js.map → RunAsSelector-BEKUP0p2.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-Cv9q8Bvt.js → ScanCodesPage-Bd0Pflqx.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-Cv9q8Bvt.js.map → ScanCodesPage-Bd0Pflqx.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-BxazXYIc.js → ScanSchemeDetailPage-CnuhozmJ.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-BxazXYIc.js.map → ScanSchemeDetailPage-CnuhozmJ.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-CoLc-q3h.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-CoLc-q3h.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-DsdtYoXR.js → StickyPagination-COrfvkBi.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-DsdtYoXR.js.map → StickyPagination-COrfvkBi.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-CT3FQoT3.js → StreamMessageDetail-Cif2egLy.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-CT3FQoT3.js.map → StreamMessageDetail-Cif2egLy.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-C8TjkJ10.js → SwimlaneTimeline-BnZYTrAh.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-C8TjkJ10.js.map → SwimlaneTimeline-BnZYTrAh.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-DGUzdBFN.js → TaskDetailPage-DEz_dqyR.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-DGUzdBFN.js.map → TaskDetailPage-DEz_dqyR.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BVIP6-EZ.js → TasksListPage-oEfEGj0_.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BVIP6-EZ.js.map → TasksListPage-oEfEGj0_.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-C-rd9F9g.js → TimeAgo-Dz5TgZZZ.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-C-rd9F9g.js.map → TimeAgo-Dz5TgZZZ.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DPbchDOI.js → TimestampCell-BUTgE244.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DPbchDOI.js.map → TimestampCell-BUTgE244.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-DAUC8DHK.js → ToolTestPanel-BS4g6vt-.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-DAUC8DHK.js.map → ToolTestPanel-BS4g6vt-.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-70mMKBzG.js → TopicDetailPage-C_I6JIVD.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-70mMKBzG.js.map → TopicDetailPage-C_I6JIVD.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-CE3hBthn.js → TopicsPage-Cr6-wfhJ.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-CE3hBthn.js.map → TopicsPage-Cr6-wfhJ.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BDBDA-LR.js → UserName-ZFpWMaFF.js} +2 -2
- package/dashboard/dist/assets/{UserName-BDBDA-LR.js.map → UserName-ZFpWMaFF.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BbkLZ1co.js → WorkflowExecutionPage-ByPixDZW.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BbkLZ1co.js.map → WorkflowExecutionPage-ByPixDZW.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-Bp1L7Ggz.js → WorkflowsDashboard-CWsJdMdR.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-Bp1L7Ggz.js.map → WorkflowsDashboard-CWsJdMdR.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-IeTKHAi4.js → WorkflowsOverview-Dk9gyqZN.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-IeTKHAi4.js.map → WorkflowsOverview-Dk9gyqZN.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DtKCXnKt.js → YamlWorkflowDetailPage-CHwcrsaT.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DtKCXnKt.js.map → YamlWorkflowDetailPage-CHwcrsaT.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CEcZBV_3.js → YamlWorkflowsPage-B5jRX2Ph.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CEcZBV_3.js.map → YamlWorkflowsPage-B5jRX2Ph.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BT-sEk81.js → agents-Dd7E-27d.js} +2 -2
- package/dashboard/dist/assets/{agents-BT-sEk81.js.map → agents-Dd7E-27d.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DRoAdLek.js → bots-CpaYjZTk.js} +2 -2
- package/dashboard/dist/assets/{bots-DRoAdLek.js.map → bots-CpaYjZTk.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-Bc-nJk6y.js → capabilities-CNjg_qv1.js} +2 -2
- package/dashboard/dist/assets/{capabilities-Bc-nJk6y.js.map → capabilities-CNjg_qv1.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-aXceSIRf.js → controlplane-DgmvnAtU.js} +2 -2
- package/dashboard/dist/assets/{controlplane-aXceSIRf.js.map → controlplane-DgmvnAtU.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-Uj4U9g5H.js +2 -0
- package/dashboard/dist/assets/escalation-columns-Uj4U9g5H.js.map +1 -0
- package/dashboard/dist/assets/{index-C3VTJcrp.js → index-BFASQ7_X.js} +2 -2
- package/dashboard/dist/assets/{index-C3VTJcrp.js.map → index-BFASQ7_X.js.map} +1 -1
- package/dashboard/dist/assets/{index-DH03y-UT.js → index-BT1Ms5Q5.js} +2 -2
- package/dashboard/dist/assets/{index-DH03y-UT.js.map → index-BT1Ms5Q5.js.map} +1 -1
- package/dashboard/dist/assets/{index-Djsoi8DI.js → index-BrwqtXRh.js} +2 -2
- package/dashboard/dist/assets/{index-Djsoi8DI.js.map → index-BrwqtXRh.js.map} +1 -1
- package/dashboard/dist/assets/index-BsHVgWH6.js +13 -0
- package/dashboard/dist/assets/{index-BEPKAjna.js.map → index-BsHVgWH6.js.map} +1 -1
- package/dashboard/dist/assets/index-ByBy9M3L.js +2 -0
- package/dashboard/dist/assets/{index-BCFEQEMC.js.map → index-ByBy9M3L.js.map} +1 -1
- package/dashboard/dist/assets/{index-CZyO9hRb.js → index-C_K7OlzT.js} +2 -2
- package/dashboard/dist/assets/{index-CZyO9hRb.js.map → index-C_K7OlzT.js.map} +1 -1
- package/dashboard/dist/assets/{index-Ba-s5Yb5.js → index-CnOvJz6U.js} +2 -2
- package/dashboard/dist/assets/{index-Ba-s5Yb5.js.map → index-CnOvJz6U.js.map} +1 -1
- package/dashboard/dist/assets/{index-CcgmR-7-.js → index-CtlBjl8o.js} +2 -2
- package/dashboard/dist/assets/{index-CcgmR-7-.js.map → index-CtlBjl8o.js.map} +1 -1
- package/dashboard/dist/assets/{index-DBxpyIw5.js → index-D4Dlznn9.js} +2 -2
- package/dashboard/dist/assets/{index-DBxpyIw5.js.map → index-D4Dlznn9.js.map} +1 -1
- package/dashboard/dist/assets/{index-BUYokcrl.js → index-LRYC__mE.js} +30 -30
- package/dashboard/dist/assets/index-LRYC__mE.js.map +1 -0
- package/dashboard/dist/assets/{index-DcppjzP5.css → index-MYI2_Xb3.css} +1 -1
- package/dashboard/dist/assets/index-OfO0173w.js +3 -0
- package/dashboard/dist/assets/index-OfO0173w.js.map +1 -0
- package/dashboard/dist/assets/{index-h2gX31B2.js → index-RIFT3RlO.js} +2 -2
- package/dashboard/dist/assets/{index-h2gX31B2.js.map → index-RIFT3RlO.js.map} +1 -1
- package/dashboard/dist/assets/{index-CuBGGwXf.js → index-x5z73M9N.js} +2 -2
- package/dashboard/dist/assets/{index-CuBGGwXf.js.map → index-x5z73M9N.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-BhW8V-Hq.js → knowledge-Cci_r6Kl.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BhW8V-Hq.js.map → knowledge-Cci_r6Kl.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-BYfSMQzh.js → mcp-NY4iL0L-.js} +2 -2
- package/dashboard/dist/assets/{mcp-BYfSMQzh.js.map → mcp-NY4iL0L-.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-DUJoOk_q.js → mcp-query-CbvZo_I_.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-DUJoOk_q.js.map → mcp-query-CbvZo_I_.js.map} +1 -1
- package/dashboard/dist/assets/{personas-jT1O_SB4.js → personas-Fy-f7QQd.js} +2 -2
- package/dashboard/dist/assets/{personas-jT1O_SB4.js.map → personas-Fy-f7QQd.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Bp-wIaz2.js → pipelines-DKiuozxV.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Bp-wIaz2.js.map → pipelines-DKiuozxV.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CCrvnXbz.js → tasks-CdM1Rkk9.js} +2 -2
- package/dashboard/dist/assets/{tasks-CCrvnXbz.js.map → tasks-CdM1Rkk9.js.map} +1 -1
- package/dashboard/dist/assets/{topics-Blft0I1L.js → topics-XNy2mf3n.js} +2 -2
- package/dashboard/dist/assets/{topics-Blft0I1L.js.map → topics-XNy2mf3n.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-BYqbcism.js → useDebouncedValue-CyGcU3_S.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-BYqbcism.js.map → useDebouncedValue-CyGcU3_S.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-BfxJAUgG.js → useNamespace-C2RIh_IN.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-BfxJAUgG.js.map → useNamespace-C2RIh_IN.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BukJuWpb.js → useYamlActivityEvents-CDiV5fjf.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BukJuWpb.js.map → useYamlActivityEvents-CDiV5fjf.js.map} +1 -1
- package/dashboard/dist/assets/validate-DcGWN82Y.js +2 -0
- package/dashboard/dist/assets/validate-DcGWN82Y.js.map +1 -0
- package/dashboard/dist/assets/{yaml-workflows-DeRWqMGk.js → yaml-workflows-CH8UrouH.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DeRWqMGk.js.map → yaml-workflows-CH8UrouH.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +46 -0
- package/docs/api/sdk/escalations.md +16 -0
- package/docs/code-owned-configuration.md +12 -0
- package/docs/hitl/portal.md +2 -0
- package/docs/hitl/x-lt-list-schema.md +88 -1
- package/docs/hitl/x-lt-scan.md +4 -1
- package/docs/scan-codes.md +7 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-CWMyy3IL.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CWMyy3IL.js.map +0 -1
- package/dashboard/dist/assets/CapabilitiesPage-DKxLvOfB.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-BUBl_4mP.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-BUBl_4mP.js.map +0 -1
- package/dashboard/dist/assets/DataTable-spX1dFyb.js +0 -2
- package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +0 -1
- package/dashboard/dist/assets/EscalationListView-DTIVuym4.js +0 -2
- package/dashboard/dist/assets/EscalationListView-DTIVuym4.js.map +0 -1
- package/dashboard/dist/assets/EscalationTimeline-DNKNp6pL.js +0 -2
- package/dashboard/dist/assets/EscalationTimeline-DNKNp6pL.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-B2DA7n9m.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-C8RtPv8P.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-C8RtPv8P.js.map +0 -1
- package/dashboard/dist/assets/PortalPage-Xk1zVneM.js +0 -2
- package/dashboard/dist/assets/PortalPage-Xk1zVneM.js.map +0 -1
- package/dashboard/dist/assets/ResolverForm-BwVOJUpJ.js +0 -8
- package/dashboard/dist/assets/ResolverForm-BwVOJUpJ.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-Cg8LCFR7.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-Cg8LCFR7.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-Bf09Q89t.js +0 -2
- package/dashboard/dist/assets/escalation-columns-Bf09Q89t.js.map +0 -1
- package/dashboard/dist/assets/index-BCFEQEMC.js +0 -2
- package/dashboard/dist/assets/index-BEPKAjna.js +0 -13
- package/dashboard/dist/assets/index-BUYokcrl.js.map +0 -1
- package/dashboard/dist/assets/index-D1mKf_qz.js +0 -3
- package/dashboard/dist/assets/index-D1mKf_qz.js.map +0 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* consolidation-sim: drive the consolidation example over HTTP so the
|
|
4
|
+
* Consolidate list shows a floor in motion.
|
|
5
|
+
*
|
|
6
|
+
* Opens a tub per destination (the first tub split into a standard and an
|
|
7
|
+
* express lane), starts orders with a mix of service levels, then walks
|
|
8
|
+
* them through the stations (prep, check) and places each in its
|
|
9
|
+
* destination's bin. With KEEP=1 it stops partway, leaving orders at every
|
|
10
|
+
* station and some bins partly filled, so the list's Holds and Coming
|
|
11
|
+
* columns and each row's expansion have something to show.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* npm run consolidation:sim
|
|
15
|
+
* DESTINATIONS=3 ORDERS=12 EXPRESS_PCT=30 KEEP=1 npm run consolidation:sim
|
|
16
|
+
*
|
|
17
|
+
* Env vars:
|
|
18
|
+
* BASE_URL long-tail API (default http://localhost:3000)
|
|
19
|
+
* DESTINATIONS destinations, one tub each (default 2)
|
|
20
|
+
* ORDERS orders to start (default 8)
|
|
21
|
+
* EXPRESS_PCT percent of orders on the express service (default 25)
|
|
22
|
+
* STEP_MS pause between floor moves (default 600)
|
|
23
|
+
* KEEP 1 = stop partway and leave the floor mid-flight (default 0)
|
|
24
|
+
* LT_USERNAME / LT_PASSWORD the dev login (defaults: the seeded admin)
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
|
|
28
|
+
const DESTINATIONS = Number(process.env.DESTINATIONS || 2);
|
|
29
|
+
const ORDERS = Number(process.env.ORDERS || 8);
|
|
30
|
+
const EXPRESS_PCT = Number(process.env.EXPRESS_PCT || 25);
|
|
31
|
+
const STEP_MS = Number(process.env.STEP_MS || 600);
|
|
32
|
+
const KEEP = process.env.KEEP === '1';
|
|
33
|
+
const USERNAME = process.env.LT_USERNAME || 'superadmin';
|
|
34
|
+
const PASSWORD = process.env.LT_PASSWORD || 'l0ngt@1l';
|
|
35
|
+
const ROLES = { PREP: 'order-prep', CHECK: 'order-check', STAGE: 'order-stage', BIN: 'consolidate' };
|
|
36
|
+
const RUN = Date.now().toString(36).slice(-4).toUpperCase();
|
|
37
|
+
const DESTINATION_NAMES = ['north', 'south', 'east', 'west', 'central', 'harbor'];
|
|
38
|
+
let token = '';
|
|
39
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
40
|
+
async function api(method, path, body) {
|
|
41
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
42
|
+
method,
|
|
43
|
+
headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}) },
|
|
44
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
45
|
+
});
|
|
46
|
+
const text = await res.text();
|
|
47
|
+
const data = text ? JSON.parse(text) : {};
|
|
48
|
+
if (!res.ok)
|
|
49
|
+
throw new Error(`${method} ${path} → ${res.status}: ${data.error ?? text}`);
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
/** The pending row for one order at one role, polled until the workflow parks it. */
|
|
53
|
+
async function rowFor(role, facets) {
|
|
54
|
+
const q = new URLSearchParams({ role, status: 'pending', limit: '1', facets: JSON.stringify(facets) });
|
|
55
|
+
for (let i = 0; i < 100; i++) {
|
|
56
|
+
const { escalations } = await api('GET', `/api/escalations?${q}`);
|
|
57
|
+
if (escalations[0])
|
|
58
|
+
return escalations[0];
|
|
59
|
+
await sleep(200);
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`no pending ${role} row for ${JSON.stringify(facets)}`);
|
|
62
|
+
}
|
|
63
|
+
async function openBins(destinations) {
|
|
64
|
+
const bins = [];
|
|
65
|
+
for (const [i, destination] of destinations.entries()) {
|
|
66
|
+
const binKey = `T${i + 1}-${RUN}`;
|
|
67
|
+
const lanes = i === 0 ? ['standard', 'express'] : [undefined];
|
|
68
|
+
for (const lane of lanes) {
|
|
69
|
+
await api('POST', '/api/workflows/consolidationBin/invoke', { data: { binKey, destination, lane, max: 20, timeout: '8h' } });
|
|
70
|
+
const row = await rowFor(ROLES.BIN, { binKey, ...(lane ? { lane } : {}) });
|
|
71
|
+
bins.push({ id: row.id, destination, lane });
|
|
72
|
+
console.log(`[bin] ${binKey}${lane ? ` (${lane})` : ''} → ${destination}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return bins;
|
|
76
|
+
}
|
|
77
|
+
async function startOrders(destinations) {
|
|
78
|
+
const orders = [];
|
|
79
|
+
for (let i = 0; i < ORDERS; i++) {
|
|
80
|
+
const order = {
|
|
81
|
+
orderId: `O${RUN}-${String(i + 1).padStart(2, '0')}`,
|
|
82
|
+
destination: destinations[i % destinations.length],
|
|
83
|
+
serviceLevel: Math.random() * 100 < EXPRESS_PCT ? 'express' : 'standard',
|
|
84
|
+
};
|
|
85
|
+
await api('POST', '/api/workflows/consolidationOrder/invoke', { data: order });
|
|
86
|
+
orders.push(order);
|
|
87
|
+
console.log(`[order] ${order.orderId} → ${order.destination} (${order.serviceLevel})`);
|
|
88
|
+
}
|
|
89
|
+
return orders;
|
|
90
|
+
}
|
|
91
|
+
async function finish(role, order) {
|
|
92
|
+
const row = await rowFor(role, { orderId: order.orderId });
|
|
93
|
+
await api('POST', `/api/escalations/${row.id}/resolve`, { resolverPayload: { ok: true } });
|
|
94
|
+
console.log(`[${role}] ${order.orderId} done`);
|
|
95
|
+
await sleep(STEP_MS);
|
|
96
|
+
}
|
|
97
|
+
async function place(order, bins) {
|
|
98
|
+
const bin = bins.find((b) => b.destination === order.destination && (!b.lane || b.lane === order.serviceLevel));
|
|
99
|
+
const member = await rowFor(ROLES.STAGE, { orderId: order.orderId });
|
|
100
|
+
await api('POST', `/api/escalations/${bin.id}/accumulate`, {
|
|
101
|
+
itemKey: order.orderId, payload: { weight: 1 }, reciprocal: { id: member.id },
|
|
102
|
+
});
|
|
103
|
+
console.log(`[place] ${order.orderId} → ${bin.destination}${bin.lane ? ` (${bin.lane})` : ''}`);
|
|
104
|
+
await sleep(STEP_MS);
|
|
105
|
+
}
|
|
106
|
+
async function main() {
|
|
107
|
+
const auth = await api('POST', '/api/auth/login', { username: USERNAME, password: PASSWORD });
|
|
108
|
+
token = auth.token;
|
|
109
|
+
const destinations = DESTINATION_NAMES.slice(0, Math.max(1, Math.min(DESTINATIONS, DESTINATION_NAMES.length)))
|
|
110
|
+
.map((d) => `${d}-${RUN}`);
|
|
111
|
+
// 1. Open the tubs, then start the orders at the first station.
|
|
112
|
+
const bins = await openBins(destinations);
|
|
113
|
+
const orders = await startOrders(destinations);
|
|
114
|
+
// 2. Walk the orders. Mid-flight (KEEP=1): a quarter stays at prep, a
|
|
115
|
+
// quarter at check, a quarter staged, the rest placed.
|
|
116
|
+
const quarter = Math.ceil(orders.length / 4);
|
|
117
|
+
for (const [i, order] of orders.entries()) {
|
|
118
|
+
if (KEEP && i < quarter)
|
|
119
|
+
continue;
|
|
120
|
+
await finish(ROLES.PREP, order);
|
|
121
|
+
if (KEEP && i < quarter * 2)
|
|
122
|
+
continue;
|
|
123
|
+
await finish(ROLES.CHECK, order);
|
|
124
|
+
if (KEEP && i < quarter * 3)
|
|
125
|
+
continue;
|
|
126
|
+
await place(order, bins);
|
|
127
|
+
}
|
|
128
|
+
// 3. A mis-placed order comes back out: the bin's count drops by one.
|
|
129
|
+
const placed = KEEP ? orders.slice(quarter * 3) : orders;
|
|
130
|
+
const last = placed[placed.length - 1];
|
|
131
|
+
if (last) {
|
|
132
|
+
const bin = bins.find((b) => b.destination === last.destination && (!b.lane || b.lane === last.serviceLevel));
|
|
133
|
+
await api('POST', `/api/escalations/${bin.id}/remove-item`, { itemKey: last.orderId });
|
|
134
|
+
console.log(`[remove] ${last.orderId} out of ${bin.destination}`);
|
|
135
|
+
}
|
|
136
|
+
console.log(`\nDone (run ${RUN}). Open the Consolidate list: ${BASE_URL}/escalations/available?role=${ROLES.BIN}`);
|
|
137
|
+
}
|
|
138
|
+
main().catch((err) => {
|
|
139
|
+
console.error(`[consolidation-sim] ${err.message}`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
});
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -291,6 +291,18 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
291
291
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
292
292
|
aggregateByFacets: (input: import("..").AggregateByFacetsInput, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
293
293
|
timelineByFacet: (input: import("..").TimelineByFacetInput, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
294
|
+
getRelated: (input: {
|
|
295
|
+
role: string;
|
|
296
|
+
ids: string[];
|
|
297
|
+
version?: number;
|
|
298
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
299
|
+
getRelatedRows: (input: {
|
|
300
|
+
role: string;
|
|
301
|
+
id: string;
|
|
302
|
+
set: string;
|
|
303
|
+
version?: number;
|
|
304
|
+
limit?: number;
|
|
305
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
294
306
|
};
|
|
295
307
|
workflows: {
|
|
296
308
|
invoke: (input: {
|
package/build/sdk/index.js
CHANGED
|
@@ -162,6 +162,8 @@ function createClient(options = {}) {
|
|
|
162
162
|
// Analytics surface (grouped membership/dwell + per-entity timeline), read_all-gated.
|
|
163
163
|
aggregateByFacets: bindAuth(escalationsApi.aggregateByFacets, auth),
|
|
164
164
|
timelineByFacet: bindAuth(escalationsApi.timelineByFacet, auth),
|
|
165
|
+
getRelated: bindAuth(escalationsApi.getRelatedAggregates, auth),
|
|
166
|
+
getRelatedRows: bindAuth(escalationsApi.getRelatedRows, auth),
|
|
165
167
|
},
|
|
166
168
|
// ── Workflows ──────────────────────────────────────────────────────────
|
|
167
169
|
workflows: {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LTEscalationRecord } from '../../types';
|
|
2
|
+
import { type ScopedFacetSearch } from './queries';
|
|
3
|
+
/** One page group: the shared facet value (null for a row without it) and its rows. */
|
|
4
|
+
export interface EscalationGroup {
|
|
5
|
+
key: string | null;
|
|
6
|
+
ids: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Scoped faceted search paged by groups of a metadata facet. A page holds
|
|
10
|
+
* whole groups, so a group never splits across pages; a row without the
|
|
11
|
+
* facet is a group of one. `total` counts groups.
|
|
12
|
+
*/
|
|
13
|
+
export declare function searchEscalationsGrouped(opts: ScopedFacetSearch & {
|
|
14
|
+
groupKey: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
escalations: LTEscalationRecord[];
|
|
17
|
+
total: number;
|
|
18
|
+
groups: EscalationGroup[];
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.searchEscalationsGrouped = searchEscalationsGrouped;
|
|
4
|
+
const db_1 = require("../../lib/db");
|
|
5
|
+
const client_1 = require("./client");
|
|
6
|
+
const facet_sql_1 = require("./facet-sql");
|
|
7
|
+
const map_1 = require("./map");
|
|
8
|
+
const queries_1 = require("./queries");
|
|
9
|
+
const SINGLETON_PREFIX = 'id:';
|
|
10
|
+
/**
|
|
11
|
+
* Scoped faceted search paged by groups of a metadata facet. A page holds
|
|
12
|
+
* whole groups, so a group never splits across pages; a row without the
|
|
13
|
+
* facet is a group of one. `total` counts groups.
|
|
14
|
+
*/
|
|
15
|
+
async function searchEscalationsGrouped(opts) {
|
|
16
|
+
if (!facet_sql_1.FACET_KEY.test(opts.groupKey))
|
|
17
|
+
throw new Error(`groupBy must be a metadata key, got "${opts.groupKey}"`);
|
|
18
|
+
await (0, client_1.ensureEscalationCompatView)();
|
|
19
|
+
const pool = (0, db_1.getPool)();
|
|
20
|
+
const groupExpr = `COALESCE(metadata->>'${opts.groupKey}', '${SINGLETON_PREFIX}' || id::text)`;
|
|
21
|
+
const params = [];
|
|
22
|
+
const where = (0, queries_1.buildScopedSearchWhere)(opts, params);
|
|
23
|
+
const countParams = [...params];
|
|
24
|
+
const li = params.push(opts.limit);
|
|
25
|
+
const oi = params.push(opts.offset);
|
|
26
|
+
const [page, count] = await Promise.all([
|
|
27
|
+
pool.query(`SELECT ${groupExpr} AS g, bool_or(metadata->>'${opts.groupKey}' IS NOT NULL) AS keyed
|
|
28
|
+
FROM public.lt_escalations ${where}
|
|
29
|
+
GROUP BY 1 ORDER BY ${(0, facet_sql_1.buildGroupOrder)(opts.facet.orderBy)}, 1
|
|
30
|
+
LIMIT $${li} OFFSET $${oi}`, params),
|
|
31
|
+
pool.query(`SELECT count(DISTINCT ${groupExpr})::int AS total FROM public.lt_escalations ${where}`, countParams),
|
|
32
|
+
]);
|
|
33
|
+
const keys = page.rows.map((r) => r.g);
|
|
34
|
+
const keyed = new Set(page.rows.filter((r) => r.keyed).map((r) => r.g));
|
|
35
|
+
const total = count.rows[0]?.total ?? 0;
|
|
36
|
+
if (!keys.length)
|
|
37
|
+
return { escalations: [], total, groups: [] };
|
|
38
|
+
const memberParams = [];
|
|
39
|
+
const memberWhere = (0, queries_1.buildScopedSearchWhere)(opts, memberParams);
|
|
40
|
+
const ki = memberParams.push(keys);
|
|
41
|
+
const keyClause = `${groupExpr} = ANY($${ki}::text[])`;
|
|
42
|
+
const members = await pool.query(`SELECT *, ${groupExpr} AS lt_group FROM public.lt_escalations
|
|
43
|
+
${memberWhere ? `${memberWhere} AND ${keyClause}` : `WHERE ${keyClause}`}
|
|
44
|
+
ORDER BY ${(0, facet_sql_1.buildFacetOrder)(opts.facet.orderBy)}`, memberParams);
|
|
45
|
+
const byKey = new Map(keys.map((k) => [k, []]));
|
|
46
|
+
for (const row of members.rows)
|
|
47
|
+
byKey.get(row.lt_group)?.push(row.id);
|
|
48
|
+
const groups = keys.map((k) => ({
|
|
49
|
+
key: keyed.has(k) ? k : null,
|
|
50
|
+
ids: byKey.get(k) ?? [],
|
|
51
|
+
}));
|
|
52
|
+
const escalations = (0, map_1.toEscalationRecords)(members.rows.map(({ lt_group: _g, ...rest }) => rest));
|
|
53
|
+
return { escalations, total, groups };
|
|
54
|
+
}
|
|
@@ -10,3 +10,7 @@ export { ensureEscalationCompatView } from './client';
|
|
|
10
10
|
export { ensureFacetReady, searchByFacets, searchGroups, countByFacets, claimGroups, claimByFacets, } from './facets';
|
|
11
11
|
export { aggregateByFacets, timelineByFacet, resolveEntitySystem, resetAnalyticsCaches, } from './aggregates';
|
|
12
12
|
export { AnalyticsInputError } from './aggregate-validate';
|
|
13
|
+
export { searchEscalationsGrouped } from './grouped-list';
|
|
14
|
+
export type { EscalationGroup } from './grouped-list';
|
|
15
|
+
export { aggregateRelatedItems, listRelatedItems, aggregateRelatedQuery, listRelatedQueryRows, readRelatedHosts, } from './related';
|
|
16
|
+
export type { RelatedQueryHost } from './related';
|
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.AnalyticsInputError = exports.resetAnalyticsCaches = exports.resolveEntitySystem = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.countByFacets = exports.searchGroups = exports.searchByFacets = exports.ensureFacetReady = exports.ensureEscalationCompatView = exports.claimAssertedByMetadata = void 0;
|
|
17
|
+
exports.readRelatedHosts = exports.listRelatedQueryRows = exports.aggregateRelatedQuery = exports.listRelatedItems = exports.aggregateRelatedItems = exports.searchEscalationsGrouped = exports.AnalyticsInputError = exports.resetAnalyticsCaches = exports.resolveEntitySystem = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.countByFacets = exports.searchGroups = exports.searchByFacets = exports.ensureFacetReady = exports.ensureEscalationCompatView = exports.claimAssertedByMetadata = void 0;
|
|
18
18
|
__exportStar(require("./types"), exports);
|
|
19
19
|
__exportStar(require("./crud"), exports);
|
|
20
20
|
var claim_asserted_1 = require("./claim-asserted");
|
|
@@ -40,3 +40,11 @@ Object.defineProperty(exports, "resolveEntitySystem", { enumerable: true, get: f
|
|
|
40
40
|
Object.defineProperty(exports, "resetAnalyticsCaches", { enumerable: true, get: function () { return aggregates_1.resetAnalyticsCaches; } });
|
|
41
41
|
var aggregate_validate_1 = require("./aggregate-validate");
|
|
42
42
|
Object.defineProperty(exports, "AnalyticsInputError", { enumerable: true, get: function () { return aggregate_validate_1.AnalyticsInputError; } });
|
|
43
|
+
var grouped_list_1 = require("./grouped-list");
|
|
44
|
+
Object.defineProperty(exports, "searchEscalationsGrouped", { enumerable: true, get: function () { return grouped_list_1.searchEscalationsGrouped; } });
|
|
45
|
+
var related_1 = require("./related");
|
|
46
|
+
Object.defineProperty(exports, "aggregateRelatedItems", { enumerable: true, get: function () { return related_1.aggregateRelatedItems; } });
|
|
47
|
+
Object.defineProperty(exports, "listRelatedItems", { enumerable: true, get: function () { return related_1.listRelatedItems; } });
|
|
48
|
+
Object.defineProperty(exports, "aggregateRelatedQuery", { enumerable: true, get: function () { return related_1.aggregateRelatedQuery; } });
|
|
49
|
+
Object.defineProperty(exports, "listRelatedQueryRows", { enumerable: true, get: function () { return related_1.listRelatedQueryRows; } });
|
|
50
|
+
Object.defineProperty(exports, "readRelatedHosts", { enumerable: true, get: function () { return related_1.readRelatedHosts; } });
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import type { LTEscalationRecord, LTEscalationStatus } from '../../types';
|
|
2
2
|
import type { EscalationStats, StationMetric } from './types';
|
|
3
3
|
import type { FacetQuery } from '../../types';
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
* predicate (global → none; else `role ∈ allRoles OR (role ∈ selfRoles AND
|
|
7
|
-
* assigned_to = me)`) with the full FacetQuery language (`buildFacetWhere`:
|
|
8
|
-
* facets `@>`, block, numeric range, exists, status, available) plus the extra
|
|
9
|
-
* top-level filters (type/subtype/priority/assigned_to) and an exact correlation-id
|
|
10
|
-
* match (id/workflow_id/origin_id), then orders
|
|
11
|
-
* by `buildFacetOrder` (columns + `metadata.<key>`). Every value is bound; the
|
|
12
|
-
* COUNT shares the WHERE so totals stay correct across pages — no client-side
|
|
13
|
-
* filtering. Reads go through the `public.lt_escalations` view.
|
|
14
|
-
*/
|
|
15
|
-
export declare function searchEscalationsFaceted(opts: {
|
|
4
|
+
/** The scoped faceted search input, shared by the row and grouped reads. */
|
|
5
|
+
export type ScopedFacetSearch = {
|
|
16
6
|
global?: boolean;
|
|
17
7
|
visibleRoles?: string[];
|
|
18
8
|
selfRoles?: string[];
|
|
@@ -25,7 +15,21 @@ export declare function searchEscalationsFaceted(opts: {
|
|
|
25
15
|
search?: string;
|
|
26
16
|
limit: number;
|
|
27
17
|
offset: number;
|
|
28
|
-
}
|
|
18
|
+
};
|
|
19
|
+
/** The WHERE clause of a scoped faceted search, pushing bound params. */
|
|
20
|
+
export declare function buildScopedSearchWhere(opts: Omit<ScopedFacetSearch, 'limit' | 'offset'>, params: unknown[]): string;
|
|
21
|
+
/**
|
|
22
|
+
* Scoped faceted search — the HUMAN operations query. Composes the read-scope
|
|
23
|
+
* predicate (global → none; else `role ∈ allRoles OR (role ∈ selfRoles AND
|
|
24
|
+
* assigned_to = me)`) with the full FacetQuery language (`buildFacetWhere`:
|
|
25
|
+
* facets `@>`, block, numeric range, exists, status, available) plus the extra
|
|
26
|
+
* top-level filters (type/subtype/priority/assigned_to) and an exact correlation-id
|
|
27
|
+
* match (id/workflow_id/origin_id), then orders
|
|
28
|
+
* by `buildFacetOrder` (columns + `metadata.<key>`). Every value is bound; the
|
|
29
|
+
* COUNT shares the WHERE so totals stay correct across pages — no client-side
|
|
30
|
+
* filtering. Reads go through the `public.lt_escalations` view.
|
|
31
|
+
*/
|
|
32
|
+
export declare function searchEscalationsFaceted(opts: ScopedFacetSearch): Promise<{
|
|
29
33
|
escalations: LTEscalationRecord[];
|
|
30
34
|
total: number;
|
|
31
35
|
}>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildScopedSearchWhere = buildScopedSearchWhere;
|
|
3
4
|
exports.searchEscalationsFaceted = searchEscalationsFaceted;
|
|
4
5
|
exports.getEscalationWithFormSchema = getEscalationWithFormSchema;
|
|
5
6
|
exports.listFacetKeys = listFacetKeys;
|
|
@@ -15,6 +16,7 @@ const db_1 = require("../../lib/db");
|
|
|
15
16
|
const client_1 = require("./client");
|
|
16
17
|
const map_1 = require("./map");
|
|
17
18
|
const facet_sql_1 = require("./facet-sql");
|
|
19
|
+
const read_scope_sql_1 = require("./read-scope-sql");
|
|
18
20
|
const types_1 = require("./types");
|
|
19
21
|
const sql_1 = require("./sql");
|
|
20
22
|
const metrics_cache_1 = require("./metrics-cache");
|
|
@@ -88,31 +90,13 @@ async function searchEscalations(params) {
|
|
|
88
90
|
total: countRows.rows[0]?.total ?? 0,
|
|
89
91
|
};
|
|
90
92
|
}
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
* predicate (global → none; else `role ∈ allRoles OR (role ∈ selfRoles AND
|
|
94
|
-
* assigned_to = me)`) with the full FacetQuery language (`buildFacetWhere`:
|
|
95
|
-
* facets `@>`, block, numeric range, exists, status, available) plus the extra
|
|
96
|
-
* top-level filters (type/subtype/priority/assigned_to) and an exact correlation-id
|
|
97
|
-
* match (id/workflow_id/origin_id), then orders
|
|
98
|
-
* by `buildFacetOrder` (columns + `metadata.<key>`). Every value is bound; the
|
|
99
|
-
* COUNT shares the WHERE so totals stay correct across pages — no client-side
|
|
100
|
-
* filtering. Reads go through the `public.lt_escalations` view.
|
|
101
|
-
*/
|
|
102
|
-
async function searchEscalationsFaceted(opts) {
|
|
103
|
-
await (0, client_1.ensureEscalationCompatView)();
|
|
104
|
-
const pool = (0, db_1.getPool)();
|
|
105
|
-
const params = [];
|
|
93
|
+
/** The WHERE clause of a scoped faceted search, pushing bound params. */
|
|
94
|
+
function buildScopedSearchWhere(opts, params) {
|
|
106
95
|
const clauses = [];
|
|
107
96
|
// 1. Read-scope predicate (skip entirely for global access).
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const mi = params.push(opts.meUserId || null);
|
|
112
|
-
clauses.push(`(($${ai}::text[] IS NULL AND $${si}::text[] IS NULL)
|
|
113
|
-
OR ($${ai}::text[] IS NOT NULL AND role = ANY($${ai}))
|
|
114
|
-
OR ($${si}::text[] IS NOT NULL AND role = ANY($${si}) AND assigned_to = $${mi}))`);
|
|
115
|
-
}
|
|
97
|
+
const scopeClause = (0, read_scope_sql_1.buildReadScopeClause)(opts, params);
|
|
98
|
+
if (scopeClause)
|
|
99
|
+
clauses.push(scopeClause);
|
|
116
100
|
// 2. Faceted predicate (role/roles/status/available/facets/block/range/exists).
|
|
117
101
|
const facetClause = (0, facet_sql_1.buildFacetWhere)(opts.facet, params);
|
|
118
102
|
if (facetClause !== 'TRUE')
|
|
@@ -135,7 +119,24 @@ async function searchEscalationsFaceted(opts) {
|
|
|
135
119
|
const u = params.push(asUuidOrNull(opts.search));
|
|
136
120
|
clauses.push(`(origin_id = $${i} OR workflow_id = $${i} OR ($${u}::uuid IS NOT NULL AND id = $${u}::uuid))`);
|
|
137
121
|
}
|
|
138
|
-
|
|
122
|
+
return clauses.length ? `WHERE ${clauses.join('\n AND ')}` : '';
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Scoped faceted search — the HUMAN operations query. Composes the read-scope
|
|
126
|
+
* predicate (global → none; else `role ∈ allRoles OR (role ∈ selfRoles AND
|
|
127
|
+
* assigned_to = me)`) with the full FacetQuery language (`buildFacetWhere`:
|
|
128
|
+
* facets `@>`, block, numeric range, exists, status, available) plus the extra
|
|
129
|
+
* top-level filters (type/subtype/priority/assigned_to) and an exact correlation-id
|
|
130
|
+
* match (id/workflow_id/origin_id), then orders
|
|
131
|
+
* by `buildFacetOrder` (columns + `metadata.<key>`). Every value is bound; the
|
|
132
|
+
* COUNT shares the WHERE so totals stay correct across pages — no client-side
|
|
133
|
+
* filtering. Reads go through the `public.lt_escalations` view.
|
|
134
|
+
*/
|
|
135
|
+
async function searchEscalationsFaceted(opts) {
|
|
136
|
+
await (0, client_1.ensureEscalationCompatView)();
|
|
137
|
+
const pool = (0, db_1.getPool)();
|
|
138
|
+
const params = [];
|
|
139
|
+
const where = buildScopedSearchWhere(opts, params);
|
|
139
140
|
const orderBy = (0, facet_sql_1.buildFacetOrder)(opts.facet.orderBy);
|
|
140
141
|
const countParams = [...params];
|
|
141
142
|
const li = params.push(opts.limit);
|
|
@@ -186,14 +187,9 @@ async function listFacetKeys(opts) {
|
|
|
186
187
|
const pool = (0, db_1.getPool)();
|
|
187
188
|
const params = [];
|
|
188
189
|
const clauses = ["jsonb_typeof(metadata) = 'object'"];
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const mi = params.push(opts.meUserId || null);
|
|
193
|
-
clauses.push(`(($${ai}::text[] IS NULL AND $${si}::text[] IS NULL)
|
|
194
|
-
OR ($${ai}::text[] IS NOT NULL AND role = ANY($${ai}))
|
|
195
|
-
OR ($${si}::text[] IS NOT NULL AND role = ANY($${si}) AND assigned_to = $${mi}))`);
|
|
196
|
-
}
|
|
190
|
+
const scopeClause = (0, read_scope_sql_1.buildReadScopeClause)(opts, params);
|
|
191
|
+
if (scopeClause)
|
|
192
|
+
clauses.push(scopeClause);
|
|
197
193
|
const { rows } = await pool.query(`SELECT DISTINCT jsonb_object_keys(metadata) AS key
|
|
198
194
|
FROM public.lt_escalations
|
|
199
195
|
WHERE ${clauses.join('\n AND ')}
|
|
@@ -237,14 +233,9 @@ async function listFacetValues(key, opts) {
|
|
|
237
233
|
const pool = (0, db_1.getPool)();
|
|
238
234
|
const params = [key];
|
|
239
235
|
const clauses = ["jsonb_typeof(metadata) = 'object'", 'metadata ? $1'];
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const mi = params.push(opts.meUserId || null);
|
|
244
|
-
clauses.push(`(($${ai}::text[] IS NULL AND $${si}::text[] IS NULL)
|
|
245
|
-
OR ($${ai}::text[] IS NOT NULL AND role = ANY($${ai}))
|
|
246
|
-
OR ($${si}::text[] IS NOT NULL AND role = ANY($${si}) AND assigned_to = $${mi}))`);
|
|
247
|
-
}
|
|
236
|
+
const scopeClause = (0, read_scope_sql_1.buildReadScopeClause)(opts, params);
|
|
237
|
+
if (scopeClause)
|
|
238
|
+
clauses.push(scopeClause);
|
|
248
239
|
const { rows } = await pool.query(`SELECT DISTINCT metadata->>$1 AS value
|
|
249
240
|
FROM public.lt_escalations
|
|
250
241
|
WHERE ${clauses.join('\n AND ')}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** The caller's read scope, as the scoped escalation queries consume it. */
|
|
2
|
+
export interface ReadScopeInput {
|
|
3
|
+
global?: boolean;
|
|
4
|
+
visibleRoles?: string[];
|
|
5
|
+
selfRoles?: string[];
|
|
6
|
+
meUserId?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The read-scope predicate: `role ∈ visibleRoles OR (role ∈ selfRoles AND
|
|
10
|
+
* assigned_to = me)`. Null for global access. `alias` qualifies the columns
|
|
11
|
+
* when the query joins several escalation rows.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildReadScopeClause(scope: ReadScopeInput, params: unknown[], alias?: string): string | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildReadScopeClause = buildReadScopeClause;
|
|
4
|
+
/**
|
|
5
|
+
* The read-scope predicate: `role ∈ visibleRoles OR (role ∈ selfRoles AND
|
|
6
|
+
* assigned_to = me)`. Null for global access. `alias` qualifies the columns
|
|
7
|
+
* when the query joins several escalation rows.
|
|
8
|
+
*/
|
|
9
|
+
function buildReadScopeClause(scope, params, alias) {
|
|
10
|
+
if (scope.global)
|
|
11
|
+
return null;
|
|
12
|
+
const col = (name) => (alias ? `${alias}.${name}` : name);
|
|
13
|
+
const ai = params.push(scope.visibleRoles?.length ? scope.visibleRoles : null);
|
|
14
|
+
const si = params.push(scope.selfRoles?.length ? scope.selfRoles : null);
|
|
15
|
+
const mi = params.push(scope.meUserId || null);
|
|
16
|
+
return `(($${ai}::text[] IS NULL AND $${si}::text[] IS NULL)
|
|
17
|
+
OR ($${ai}::text[] IS NOT NULL AND ${col('role')} = ANY($${ai}))
|
|
18
|
+
OR ($${si}::text[] IS NOT NULL AND ${col('role')} = ANY($${si}) AND ${col('assigned_to')} = $${mi}))`;
|
|
19
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type RelatedHostAggregate, type RelatedRow } from '../../shared/list-schema';
|
|
2
|
+
import { type ReadScopeInput } from './read-scope-sql';
|
|
3
|
+
/** One host's resolved facet match for a query set. */
|
|
4
|
+
export interface RelatedQueryHost {
|
|
5
|
+
hostId: string;
|
|
6
|
+
match: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface RelatedQueryInput {
|
|
9
|
+
hosts: RelatedQueryHost[];
|
|
10
|
+
roles: string[];
|
|
11
|
+
status: string;
|
|
12
|
+
scope: ReadScopeInput;
|
|
13
|
+
}
|
|
14
|
+
type Aggregates = Record<string, RelatedHostAggregate>;
|
|
15
|
+
/**
|
|
16
|
+
* Count each host's items, optionally split by `payload.<path>` or
|
|
17
|
+
* `reciprocal.metadata.<key>`. A reciprocal split counts only reciprocal rows
|
|
18
|
+
* the caller can read; the rest are reported as `hidden`. `roles` names the
|
|
19
|
+
* roles of the readable reciprocal rows, so a list can follow their changes.
|
|
20
|
+
*/
|
|
21
|
+
export declare function aggregateRelatedItems(opts: {
|
|
22
|
+
hostIds: string[];
|
|
23
|
+
scope: ReadScopeInput;
|
|
24
|
+
splitBy?: string;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
aggregates: Aggregates;
|
|
27
|
+
roles: string[];
|
|
28
|
+
}>;
|
|
29
|
+
/** One host's items in fill order, each with its reciprocal row when readable. */
|
|
30
|
+
export declare function listRelatedItems(opts: {
|
|
31
|
+
hostId: string;
|
|
32
|
+
scope: ReadScopeInput;
|
|
33
|
+
limit: number;
|
|
34
|
+
}): Promise<{
|
|
35
|
+
rows: RelatedRow[];
|
|
36
|
+
total: number;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Count the rows that share each host's facets, grouped by role and an
|
|
40
|
+
* optional `metadata.<key>` split. The GIN index serves each host's match.
|
|
41
|
+
*/
|
|
42
|
+
export declare function aggregateRelatedQuery(input: RelatedQueryInput & {
|
|
43
|
+
splitBy?: string;
|
|
44
|
+
}): Promise<Aggregates>;
|
|
45
|
+
/** One host's related rows, in role order then age. */
|
|
46
|
+
export declare function listRelatedQueryRows(input: RelatedQueryInput & {
|
|
47
|
+
limit: number;
|
|
48
|
+
}): Promise<{
|
|
49
|
+
rows: RelatedRow[];
|
|
50
|
+
total: number;
|
|
51
|
+
}>;
|
|
52
|
+
/** Host rows of one role, read under the caller's scope. */
|
|
53
|
+
export declare function readRelatedHosts(opts: {
|
|
54
|
+
ids: string[];
|
|
55
|
+
role: string;
|
|
56
|
+
scope: ReadScopeInput;
|
|
57
|
+
}): Promise<Record<string, unknown>[]>;
|
|
58
|
+
export {};
|