@hotmeshio/long-tail 0.12.1 → 0.13.1
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 +1 -0
- package/build/api/auth-sso.d.ts +6 -3
- package/build/api/auth-sso.js +6 -3
- package/build/api/escalations/helpers.js +4 -2
- package/build/api/settings.js +3 -0
- package/build/modules/auth.js +9 -3
- package/build/routes/auth-sso.js +6 -1
- package/build/services/agent/index.d.ts +11 -0
- package/build/services/agent/index.js +32 -0
- package/build/services/agent/sql.d.ts +7 -0
- package/build/services/agent/sql.js +32 -1
- package/build/services/agent/subscription-sql.d.ts +6 -0
- package/build/services/agent/subscription-sql.js +32 -1
- package/build/services/agent/subscriptions.d.ts +6 -0
- package/build/services/agent/subscriptions.js +23 -0
- package/build/services/config/index.d.ts +1 -1
- package/build/services/config/index.js +2 -1
- package/build/services/config/write.d.ts +10 -0
- package/build/services/config/write.js +49 -2
- package/build/services/domain/seed.d.ts +12 -5
- package/build/services/domain/seed.js +25 -6
- package/build/services/mcp/db.d.ts +16 -0
- package/build/services/mcp/db.js +24 -0
- package/build/services/mcp/sql.d.ts +8 -0
- package/build/services/mcp/sql.js +24 -1
- package/build/services/role/seed.d.ts +21 -0
- package/build/services/role/seed.js +113 -0
- package/build/services/role/sql.d.ts +8 -0
- package/build/services/role/sql.js +24 -1
- package/build/services/scan-code/index.d.ts +1 -1
- package/build/services/scan-code/index.js +3 -1
- package/build/services/scan-code/sql.d.ts +7 -0
- package/build/services/scan-code/sql.js +55 -1
- package/build/services/scan-code/write.d.ts +8 -0
- package/build/services/scan-code/write.js +23 -1
- package/build/services/topics/index.d.ts +2 -0
- package/build/services/topics/index.js +7 -0
- package/build/services/topics/sql.d.ts +2 -0
- package/build/services/topics/sql.js +5 -1
- package/build/services/topics/system-topics.d.ts +3 -2
- package/build/services/topics/system-topics.js +4 -3
- package/build/services/user/index.d.ts +1 -1
- package/build/services/user/index.js +2 -1
- package/build/services/user/roles.d.ts +8 -0
- package/build/services/user/roles.js +29 -0
- package/build/services/user/sql.d.ts +6 -0
- package/build/services/user/sql.js +9 -1
- package/build/services/user/sso-provision.js +14 -3
- package/build/start/apply-report.d.ts +26 -0
- package/build/start/apply-report.js +65 -0
- package/build/start/config.js +8 -1
- package/build/start/workers.js +222 -33
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/auth.d.ts +44 -4
- package/build/types/index.d.ts +1 -1
- package/build/types/startup.d.ts +160 -4
- package/dashboard/dist/assets/{AdminDashboard-DpTZG5EL.js → AdminDashboard-D2unnS2b.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DpTZG5EL.js.map → AdminDashboard-D2unnS2b.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-DVTL0NvC.js → AgentConfigPage-CBkf403g.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-DVTL0NvC.js.map → AgentConfigPage-CBkf403g.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DOLKNPJl.js → AgentDetailPage-CAIU3yzo.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-DOLKNPJl.js.map → AgentDetailPage-CAIU3yzo.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-DiOZu6Xb.js → AgentsPage-qP9fWMyT.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DiOZu6Xb.js.map → AgentsPage-qP9fWMyT.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-CY5lfx27.js → AvailableEscalationsPage-DvWaiafI.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-CY5lfx27.js.map → AvailableEscalationsPage-DvWaiafI.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-ButjLJr2.js → BotPicker-BN-MKITV.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-ButjLJr2.js.map → BotPicker-BN-MKITV.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CW_r2OlX.js → CapabilitiesPage-CJfmWokN.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CW_r2OlX.js.map → CapabilitiesPage-CJfmWokN.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BOGRyCfm.js → CollapsibleSection-BvMHlHyt.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BOGRyCfm.js.map → CollapsibleSection-BvMHlHyt.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-UcHYZSg1.js → CountdownTimer-By4rbMDN.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-UcHYZSg1.js.map → CountdownTimer-By4rbMDN.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-A7OFYVsX.js → CredentialsPage-2TvvRwGJ.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-A7OFYVsX.js.map → CredentialsPage-2TvvRwGJ.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-Dve2Udsm.js → CronLabel-HxmsDSnV.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-Dve2Udsm.js.map → CronLabel-HxmsDSnV.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-BoPrA-Em.js → CustomDurationPicker-8Ao-1pKA.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-BoPrA-Em.js.map → CustomDurationPicker-8Ao-1pKA.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-B114P5mb.js → ElapsedCell-BkRu9Xpd.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-B114P5mb.js.map → ElapsedCell-BkRu9Xpd.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-BqDWyOa9.js → EntityTimelinePanel--E6hLMCM.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-BqDWyOa9.js.map → EntityTimelinePanel--E6hLMCM.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-DyyTyghx.js → EscalationListSchemaPage-CdFtqEEX.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-DyyTyghx.js.map → EscalationListSchemaPage-CdFtqEEX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-DLQG6EXQ.js → EscalationSchemaPage-BsjS2axz.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-DLQG6EXQ.js.map → EscalationSchemaPage-BsjS2axz.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-RrbkkEU0.js → EscalationsOverview-FL-xteVc.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-RrbkkEU0.js.map → EscalationsOverview-FL-xteVc.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DOxubt7O.js → EventTable-BOcgZ78i.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DOxubt7O.js.map → EventTable-BOcgZ78i.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-y659Gc3X.js → FilterBar-DfCiCmm-.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-y659Gc3X.js.map → FilterBar-DfCiCmm-.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-oHLgSAl6.js → GraphInvokePage-DfVeiN-8.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-oHLgSAl6.js.map → GraphInvokePage-DfVeiN-8.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-C9FUpD7x.js → HomePage-C2IhF9WB.js} +2 -2
- package/dashboard/dist/assets/{HomePage-C9FUpD7x.js.map → HomePage-C2IhF9WB.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-DfpSgWYU.js → ListToolbar-DA0PTOl5.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-DfpSgWYU.js.map → ListToolbar-DA0PTOl5.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-6Ubpr9QS.js → McpOverview-DstPch5M.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-6Ubpr9QS.js.map → McpOverview-DstPch5M.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DFt-vQEp.js → McpQueryDetailPage-Csv0PKE0.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DFt-vQEp.js.map → McpQueryDetailPage-Csv0PKE0.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DQiG0AE3.js → McpQueryPage-DxmqCkly.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DQiG0AE3.js.map → McpQueryPage-DxmqCkly.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-BgsSegyP.js → McpRunDetailPage-CcJOlp_B.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-BgsSegyP.js.map → McpRunDetailPage-CcJOlp_B.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-tCMxspqS.js → McpRunsPage-BZCR043j.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-tCMxspqS.js.map → McpRunsPage-BZCR043j.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DUaRmEPa.js → OperationsPage-DMsPXITh.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DUaRmEPa.js.map → OperationsPage-DMsPXITh.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-CayyjMcf.js → OperatorDashboard-DSloftQ5.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-CayyjMcf.js.map → OperatorDashboard-DSloftQ5.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-DBcxfdbN.js → PersonaDetailPage-jDVRCLbU.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-DBcxfdbN.js.map → PersonaDetailPage-jDVRCLbU.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-DPq0HQAB.js → PersonasPage-DnDDwXoy.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-DPq0HQAB.js.map → PersonasPage-DnDDwXoy.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-QQZNNNMw.js → ProcessDetailPage-CfAUU6q2.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-QQZNNNMw.js.map → ProcessDetailPage-CfAUU6q2.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-UKQMJ4Te.js → ProcessesListPage-CnAXzaVv.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-UKQMJ4Te.js.map → ProcessesListPage-CnAXzaVv.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-DT-3sSRD.js → RoleDetailPage-Dg1p6Qz_.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-DT-3sSRD.js.map → RoleDetailPage-Dg1p6Qz_.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DZg4niqL.js → RolesPage-DeRVQux8.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DZg4niqL.js.map → RolesPage-DeRVQux8.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-DkcNR7L6.js → RunAsSelector-BFNqQGuG.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DkcNR7L6.js.map → RunAsSelector-BFNqQGuG.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-U-alpwWF.js → ScanCodesPage-D0GOdk5m.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-U-alpwWF.js.map → ScanCodesPage-D0GOdk5m.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-lXwlcraS.js → ScanSchemeDetailPage-vFqoe_P4.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-lXwlcraS.js.map → ScanSchemeDetailPage-vFqoe_P4.js.map} +1 -1
- package/dashboard/dist/assets/{ScanStationPage-DYMiTp-v.js → ScanStationPage-DH1ynTX9.js} +2 -2
- package/dashboard/dist/assets/{ScanStationPage-DYMiTp-v.js.map → ScanStationPage-DH1ynTX9.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-D896Wquq.js → StickyPagination-B99hVu95.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-D896Wquq.js.map → StickyPagination-B99hVu95.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-DIh5qEGJ.js → StreamMessageDetail-DcDGISrv.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DIh5qEGJ.js.map → StreamMessageDetail-DcDGISrv.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-B8SucVj5.js → SwimlaneTimeline-BP3mSQAg.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-B8SucVj5.js.map → SwimlaneTimeline-BP3mSQAg.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-Di-z_ZE2.js → TaskDetailPage-_XWLJzt-.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-Di-z_ZE2.js.map → TaskDetailPage-_XWLJzt-.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-ClHGEdin.js → TasksListPage-iGriKiO2.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-ClHGEdin.js.map → TasksListPage-iGriKiO2.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BSDHd9Xo.js → TimeAgo-BO33VeFl.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BSDHd9Xo.js.map → TimeAgo-BO33VeFl.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-WQL3FxWl.js → TimestampCell-KAjX7w35.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-WQL3FxWl.js.map → TimestampCell-KAjX7w35.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-IVIkqZTi.js → ToolTestPanel-BchG2yC6.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-IVIkqZTi.js.map → ToolTestPanel-BchG2yC6.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BOasQo68.js → TopicDetailPage-BaK8H0o1.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-BOasQo68.js.map → TopicDetailPage-BaK8H0o1.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DV_orf_V.js → TopicsPage-DEyvm669.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DV_orf_V.js.map → TopicsPage-DEyvm669.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-rshjKBtm.js → UserName-BV6SKI9P.js} +2 -2
- package/dashboard/dist/assets/{UserName-rshjKBtm.js.map → UserName-BV6SKI9P.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BpNGLwbK.js → WorkflowExecutionPage-1sKoEFNC.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BpNGLwbK.js.map → WorkflowExecutionPage-1sKoEFNC.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-BAXt8gv_.js → WorkflowsDashboard-YTHDZZOD.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-BAXt8gv_.js.map → WorkflowsDashboard-YTHDZZOD.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-DvOyzL6y.js → WorkflowsOverview-ucXPLTtm.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-DvOyzL6y.js.map → WorkflowsOverview-ucXPLTtm.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CraijGy6.js → YamlWorkflowDetailPage-C_RTZKqZ.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CraijGy6.js.map → YamlWorkflowDetailPage-C_RTZKqZ.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CNz3ptmj.js → YamlWorkflowsPage-Usid3w2W.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CNz3ptmj.js.map → YamlWorkflowsPage-Usid3w2W.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BswSJR-t.js → agents-BTDsRK8e.js} +2 -2
- package/dashboard/dist/assets/{agents-BswSJR-t.js.map → agents-BTDsRK8e.js.map} +1 -1
- package/dashboard/dist/assets/{bots-VzlLx_GQ.js → bots-DxLrfdfr.js} +2 -2
- package/dashboard/dist/assets/{bots-VzlLx_GQ.js.map → bots-DxLrfdfr.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-B0bNlTTA.js → capabilities-DbTmeW-S.js} +2 -2
- package/dashboard/dist/assets/{capabilities-B0bNlTTA.js.map → capabilities-DbTmeW-S.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DBESTVZS.js → controlplane-CEBntAL4.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DBESTVZS.js.map → controlplane-CEBntAL4.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-CoqsCdbP.js → escalation-columns-Carqdwoh.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-CoqsCdbP.js.map → escalation-columns-Carqdwoh.js.map} +1 -1
- package/dashboard/dist/assets/{index-DUfdCp8e.js → index-B2hz0pUh.js} +2 -2
- package/dashboard/dist/assets/{index-DUfdCp8e.js.map → index-B2hz0pUh.js.map} +1 -1
- package/dashboard/dist/assets/{index-DJS-hvDt.js → index-B9m7fA3M.js} +2 -2
- package/dashboard/dist/assets/{index-DJS-hvDt.js.map → index-B9m7fA3M.js.map} +1 -1
- package/dashboard/dist/assets/{index-C_lA7ghl.js → index-BhapT-Vl.js} +2 -2
- package/dashboard/dist/assets/{index-C_lA7ghl.js.map → index-BhapT-Vl.js.map} +1 -1
- package/dashboard/dist/assets/{index-DsDFZzqr.js → index-Bqm4zu46.js} +2 -2
- package/dashboard/dist/assets/{index-DsDFZzqr.js.map → index-Bqm4zu46.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cd7jZylO.js → index-C0hSttF5.js} +2 -2
- package/dashboard/dist/assets/{index-Cd7jZylO.js.map → index-C0hSttF5.js.map} +1 -1
- package/dashboard/dist/assets/{index-ByUjwu37.js → index-CDkg6iOE.js} +2 -2
- package/dashboard/dist/assets/{index-ByUjwu37.js.map → index-CDkg6iOE.js.map} +1 -1
- package/dashboard/dist/assets/{index-Ci4lxPwS.js → index-CVBBkW8V.js} +2 -2
- package/dashboard/dist/assets/{index-Ci4lxPwS.js.map → index-CVBBkW8V.js.map} +1 -1
- package/dashboard/dist/assets/{index-DYDcjn-b.js → index-CgIBjZta.js} +2 -2
- package/dashboard/dist/assets/{index-DYDcjn-b.js.map → index-CgIBjZta.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cqrp5B5S.js → index-DBXm49S6.js} +25 -25
- package/dashboard/dist/assets/index-DBXm49S6.js.map +1 -0
- package/dashboard/dist/assets/{index-BBXmIWKx.js → index-De8iV1y2.js} +2 -2
- package/dashboard/dist/assets/{index-BBXmIWKx.js.map → index-De8iV1y2.js.map} +1 -1
- package/dashboard/dist/assets/{index-D8ljRGIb.js → index-DsgjFRvA.js} +2 -2
- package/dashboard/dist/assets/{index-D8ljRGIb.js.map → index-DsgjFRvA.js.map} +1 -1
- package/dashboard/dist/assets/{index-BLzwfbZV.js → index-kes8V4Xw.js} +2 -2
- package/dashboard/dist/assets/{index-BLzwfbZV.js.map → index-kes8V4Xw.js.map} +1 -1
- package/dashboard/dist/assets/{index-CALocCAr.js → index-nwLh3CK2.js} +2 -2
- package/dashboard/dist/assets/{index-CALocCAr.js.map → index-nwLh3CK2.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-DB2DgDa_.js → knowledge-oFYAanUp.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DB2DgDa_.js.map → knowledge-oFYAanUp.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-D72yCeuf.js → mcp-C9Kw4Ow8.js} +2 -2
- package/dashboard/dist/assets/{mcp-D72yCeuf.js.map → mcp-C9Kw4Ow8.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-Cyyc_0E8.js → mcp-query-BwzpZ91Z.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-Cyyc_0E8.js.map → mcp-query-BwzpZ91Z.js.map} +1 -1
- package/dashboard/dist/assets/{personas-xMDV7yXb.js → personas-D5ehmtRb.js} +2 -2
- package/dashboard/dist/assets/{personas-xMDV7yXb.js.map → personas-D5ehmtRb.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-mlxfmi6m.js → pipelines-xgPKGEdD.js} +2 -2
- package/dashboard/dist/assets/{pipelines-mlxfmi6m.js.map → pipelines-xgPKGEdD.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CxgOp_9H.js → tasks-CLyrl-MU.js} +2 -2
- package/dashboard/dist/assets/{tasks-CxgOp_9H.js.map → tasks-CLyrl-MU.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CFb_L0Vs.js → topics-B_gO7CQ0.js} +2 -2
- package/dashboard/dist/assets/{topics-CFb_L0Vs.js.map → topics-B_gO7CQ0.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-nC5kH-QW.js → useEventHooks-BdWYm63U.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-nC5kH-QW.js.map → useEventHooks-BdWYm63U.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DQeDgRFR.js → useNamespace-C238M4Qn.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DQeDgRFR.js.map → useNamespace-C238M4Qn.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BuGC3oBE.js → useYamlActivityEvents-B2ryEK4S.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BuGC3oBE.js.map → useYamlActivityEvents-B2ryEK4S.js.map} +1 -1
- package/dashboard/dist/assets/{users-BZUTtM_6.js → users-BFaTe6Mt.js} +2 -2
- package/dashboard/dist/assets/{users-BZUTtM_6.js.map → users-BFaTe6Mt.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DWhaZWVK.js → workflows-DXz7tZxp.js} +2 -2
- package/dashboard/dist/assets/{workflows-DWhaZWVK.js.map → workflows-DXz7tZxp.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-C1TeDIIk.js → yaml-workflows-u3xuRAnS.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-C1TeDIIk.js.map → yaml-workflows-u3xuRAnS.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/docs/auth.md +26 -1
- package/docs/code-owned-configuration.md +158 -0
- package/docs/scan-codes.md +24 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/index-Cqrp5B5S.js.map +0 -1
package/build/services/mcp/db.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.listMcpServers = listMcpServers;
|
|
|
10
10
|
exports.getAutoConnectServers = getAutoConnectServers;
|
|
11
11
|
exports.findServersByTags = findServersByTags;
|
|
12
12
|
exports.seedMcpServer = seedMcpServer;
|
|
13
|
+
exports.applyMcpServer = applyMcpServer;
|
|
13
14
|
exports.cleanStaleBuiltinServers = cleanStaleBuiltinServers;
|
|
14
15
|
const db_1 = require("../../lib/db");
|
|
15
16
|
const logger_1 = require("../../lib/logger");
|
|
@@ -190,6 +191,29 @@ async function seedMcpServer(input) {
|
|
|
190
191
|
}
|
|
191
192
|
return inserted;
|
|
192
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Apply an MCP server declaration at startup (code is source of truth).
|
|
196
|
+
* Config fields — description, tags, category, compile hints, credential
|
|
197
|
+
* providers — are written when they differ; runtime state (tool manifest,
|
|
198
|
+
* connection status) is never touched. Returns 'applied' when the row was
|
|
199
|
+
* inserted or updated, 'unchanged' when the declaration already matches.
|
|
200
|
+
*/
|
|
201
|
+
async function applyMcpServer(input) {
|
|
202
|
+
const pool = (0, db_1.getPool)();
|
|
203
|
+
const { rowCount } = await pool.query(sql_1.APPLY_MCP_SERVER, [
|
|
204
|
+
input.name,
|
|
205
|
+
input.description || null,
|
|
206
|
+
'stdio',
|
|
207
|
+
JSON.stringify({ builtin: true, process: 'in-memory' }),
|
|
208
|
+
JSON.stringify(input.toolManifest || []),
|
|
209
|
+
JSON.stringify({ builtin: true }),
|
|
210
|
+
input.tags || [],
|
|
211
|
+
input.compileHints || null,
|
|
212
|
+
input.credentialProviders || [],
|
|
213
|
+
input.category || null,
|
|
214
|
+
]);
|
|
215
|
+
return (rowCount ?? 0) > 0 ? 'applied' : 'unchanged';
|
|
216
|
+
}
|
|
193
217
|
/**
|
|
194
218
|
* Remove builtin MCP servers that are no longer declared in factory config.
|
|
195
219
|
*/
|
|
@@ -19,3 +19,11 @@ export declare const DELETE_STALE_BUILTIN_SERVERS = "\n DELETE FROM lt_mcp_serv
|
|
|
19
19
|
export declare const UPSERT_MCP_SERVER = "\n INSERT INTO lt_mcp_servers\n (name, description, transport_type, transport_config, auto_connect, status, tool_manifest, metadata, tags, compile_hints, credential_providers, last_connected_at)\n VALUES ($1, $2, $3, $4, true, 'connected', $5, $6, $7, $8, $9, NOW())\n ON CONFLICT (name) DO UPDATE SET\n tool_manifest = EXCLUDED.tool_manifest,\n metadata = EXCLUDED.metadata,\n description = EXCLUDED.description,\n tags = EXCLUDED.tags,\n compile_hints = EXCLUDED.compile_hints,\n credential_providers = EXCLUDED.credential_providers,\n status = 'connected',\n last_connected_at = NOW()";
|
|
20
20
|
/** Seed — insert-if-absent. DB is source of truth after first boot. */
|
|
21
21
|
export declare const SEED_MCP_SERVER = "\n INSERT INTO lt_mcp_servers\n (name, description, transport_type, transport_config, auto_connect, status, tool_manifest, metadata, tags, compile_hints, credential_providers, category, last_connected_at)\n VALUES ($1, $2, $3, $4, true, 'connected', $5, $6, $7, $8, $9, $10, NOW())\n ON CONFLICT (name) DO NOTHING";
|
|
22
|
+
/**
|
|
23
|
+
* Apply — code is source of truth for the CONFIG fields only. On conflict the
|
|
24
|
+
* update rewrites description/tags/category/compile_hints/credential_providers
|
|
25
|
+
* and leaves runtime state (tool_manifest, status, last_connected_at,
|
|
26
|
+
* transport_config) untouched; the IS DISTINCT FROM guard makes an unchanged
|
|
27
|
+
* declaration a zero-row no-op. `(xmax = 0)` distinguishes insert from update.
|
|
28
|
+
*/
|
|
29
|
+
export declare const APPLY_MCP_SERVER = "\n INSERT INTO lt_mcp_servers\n (name, description, transport_type, transport_config, auto_connect, status, tool_manifest, metadata, tags, compile_hints, credential_providers, category, last_connected_at)\n VALUES ($1, $2, $3, $4, true, 'connected', $5, $6, $7, $8, $9, $10, NOW())\n ON CONFLICT (name) DO UPDATE SET\n description = EXCLUDED.description,\n tags = EXCLUDED.tags,\n category = EXCLUDED.category,\n compile_hints = EXCLUDED.compile_hints,\n credential_providers = EXCLUDED.credential_providers\n WHERE (lt_mcp_servers.description, lt_mcp_servers.tags, lt_mcp_servers.category,\n lt_mcp_servers.compile_hints, lt_mcp_servers.credential_providers)\n IS DISTINCT FROM\n (EXCLUDED.description, EXCLUDED.tags, EXCLUDED.category,\n EXCLUDED.compile_hints, EXCLUDED.credential_providers)\n RETURNING (xmax = 0) AS inserted";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ─── MCP server CRUD ────────────────────────────────────────────────────────
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.SEED_MCP_SERVER = exports.UPSERT_MCP_SERVER = exports.DELETE_STALE_BUILTIN_SERVERS = exports.HEALTH_DURABLE_WORKFLOWS = exports.HEALTH_WORKFLOW_CONFIGS = exports.HEALTH_COMPILED_WORKFLOWS = exports.HEALTH_MCP_SERVER_LIST = exports.HEALTH_MCP_SERVERS = exports.HEALTH_RECENT_ACTIVITY = exports.HEALTH_ACTIVE_WORKFLOW_TYPES = exports.HEALTH_ESCALATION_COUNTS = exports.HEALTH_TASK_COUNTS = exports.GET_AUTO_CONNECT_SERVERS = exports.UPDATE_STATUS = exports.UPDATE_STATUS_CONNECTED = exports.DELETE_MCP_SERVER = exports.GET_MCP_SERVER_BY_NAME = exports.GET_MCP_SERVER = exports.CREATE_MCP_SERVER = void 0;
|
|
4
|
+
exports.APPLY_MCP_SERVER = exports.SEED_MCP_SERVER = exports.UPSERT_MCP_SERVER = exports.DELETE_STALE_BUILTIN_SERVERS = exports.HEALTH_DURABLE_WORKFLOWS = exports.HEALTH_WORKFLOW_CONFIGS = exports.HEALTH_COMPILED_WORKFLOWS = exports.HEALTH_MCP_SERVER_LIST = exports.HEALTH_MCP_SERVERS = exports.HEALTH_RECENT_ACTIVITY = exports.HEALTH_ACTIVE_WORKFLOW_TYPES = exports.HEALTH_ESCALATION_COUNTS = exports.HEALTH_TASK_COUNTS = exports.GET_AUTO_CONNECT_SERVERS = exports.UPDATE_STATUS = exports.UPDATE_STATUS_CONNECTED = exports.DELETE_MCP_SERVER = exports.GET_MCP_SERVER_BY_NAME = exports.GET_MCP_SERVER = exports.CREATE_MCP_SERVER = void 0;
|
|
5
5
|
exports.CREATE_MCP_SERVER = `
|
|
6
6
|
INSERT INTO lt_mcp_servers
|
|
7
7
|
(name, description, transport_type, transport_config, auto_connect, metadata, tags, compile_hints, credential_providers)
|
|
@@ -97,3 +97,26 @@ exports.SEED_MCP_SERVER = `
|
|
|
97
97
|
(name, description, transport_type, transport_config, auto_connect, status, tool_manifest, metadata, tags, compile_hints, credential_providers, category, last_connected_at)
|
|
98
98
|
VALUES ($1, $2, $3, $4, true, 'connected', $5, $6, $7, $8, $9, $10, NOW())
|
|
99
99
|
ON CONFLICT (name) DO NOTHING`;
|
|
100
|
+
/**
|
|
101
|
+
* Apply — code is source of truth for the CONFIG fields only. On conflict the
|
|
102
|
+
* update rewrites description/tags/category/compile_hints/credential_providers
|
|
103
|
+
* and leaves runtime state (tool_manifest, status, last_connected_at,
|
|
104
|
+
* transport_config) untouched; the IS DISTINCT FROM guard makes an unchanged
|
|
105
|
+
* declaration a zero-row no-op. `(xmax = 0)` distinguishes insert from update.
|
|
106
|
+
*/
|
|
107
|
+
exports.APPLY_MCP_SERVER = `
|
|
108
|
+
INSERT INTO lt_mcp_servers
|
|
109
|
+
(name, description, transport_type, transport_config, auto_connect, status, tool_manifest, metadata, tags, compile_hints, credential_providers, category, last_connected_at)
|
|
110
|
+
VALUES ($1, $2, $3, $4, true, 'connected', $5, $6, $7, $8, $9, $10, NOW())
|
|
111
|
+
ON CONFLICT (name) DO UPDATE SET
|
|
112
|
+
description = EXCLUDED.description,
|
|
113
|
+
tags = EXCLUDED.tags,
|
|
114
|
+
category = EXCLUDED.category,
|
|
115
|
+
compile_hints = EXCLUDED.compile_hints,
|
|
116
|
+
credential_providers = EXCLUDED.credential_providers
|
|
117
|
+
WHERE (lt_mcp_servers.description, lt_mcp_servers.tags, lt_mcp_servers.category,
|
|
118
|
+
lt_mcp_servers.compile_hints, lt_mcp_servers.credential_providers)
|
|
119
|
+
IS DISTINCT FROM
|
|
120
|
+
(EXCLUDED.description, EXCLUDED.tags, EXCLUDED.category,
|
|
121
|
+
EXCLUDED.compile_hints, EXCLUDED.credential_providers)
|
|
122
|
+
RETURNING (xmax = 0) AS inserted`;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LTRoleConfig } from '../../types/startup';
|
|
2
|
+
export type RoleApplyOutcome = 'applied' | 'unchanged' | 'db-owned';
|
|
3
|
+
/** Recorded on schema snapshots written by the startup apply. */
|
|
4
|
+
export declare const STARTUP_CHANGE_SUMMARY = "startup apply (code)";
|
|
5
|
+
/**
|
|
6
|
+
* Roles carrying real configuration (title or form schema) — the candidate
|
|
7
|
+
* set for the startup orphan report. Bare FK-ensured rows are excluded.
|
|
8
|
+
*/
|
|
9
|
+
export declare function listConfiguredRoles(): Promise<string[]>;
|
|
10
|
+
/**
|
|
11
|
+
* Register one declared role at startup.
|
|
12
|
+
*
|
|
13
|
+
* The role is created if missing. Under code ownership its declared fields
|
|
14
|
+
* are compared against the stored row and written through the versioned
|
|
15
|
+
* PATCH path when they differ — a changed form/metadata schema advances the
|
|
16
|
+
* role's schema version and snapshots the pair; an unchanged declaration is
|
|
17
|
+
* a no-op. Under db ownership the metadata is written exactly once (at
|
|
18
|
+
* creation); afterwards the DB owns the row and drift is warn-logged only.
|
|
19
|
+
* Escalation targets use replace semantics when declared.
|
|
20
|
+
*/
|
|
21
|
+
export declare function applyRoleConfig(cfg: LTRoleConfig, codeOwned: boolean): Promise<RoleApplyOutcome>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STARTUP_CHANGE_SUMMARY = void 0;
|
|
4
|
+
exports.listConfiguredRoles = listConfiguredRoles;
|
|
5
|
+
exports.applyRoleConfig = applyRoleConfig;
|
|
6
|
+
const node_util_1 = require("node:util");
|
|
7
|
+
const db_1 = require("../../lib/db");
|
|
8
|
+
const logger_1 = require("../../lib/logger");
|
|
9
|
+
const index_1 = require("./index");
|
|
10
|
+
const sql_1 = require("./sql");
|
|
11
|
+
/** Recorded on schema snapshots written by the startup apply. */
|
|
12
|
+
exports.STARTUP_CHANGE_SUMMARY = 'startup apply (code)';
|
|
13
|
+
/** Metadata fields shared 1:1 between LTRoleConfig and UpdateRoleInput. */
|
|
14
|
+
const METADATA_FIELDS = [
|
|
15
|
+
'title', 'description', 'form_schema', 'metadata_schema', 'list_schema',
|
|
16
|
+
'properties', 'ops_visible', 'ops_home_default', 'parent_role',
|
|
17
|
+
'upstream_roles', 'default_pins', 'enforce_schema', 'sla_minutes',
|
|
18
|
+
'target_per_hour', 'worker_count', 'priority_threshold_minutes',
|
|
19
|
+
'priority_facet', 'entity_facet', 'entity_state_source',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Compare one declared field against the stored row. jsonb round-trips lose
|
|
23
|
+
* key order, so structured values must be compared as parsed values — never
|
|
24
|
+
* by string. Arrays compare order-insensitively (sorted).
|
|
25
|
+
*/
|
|
26
|
+
function fieldDiffers(field, declared, row) {
|
|
27
|
+
const stored = row[field];
|
|
28
|
+
if (Array.isArray(declared)) {
|
|
29
|
+
const a = [...declared].sort();
|
|
30
|
+
const b = Array.isArray(stored) ? [...stored].sort() : [];
|
|
31
|
+
return !(0, node_util_1.isDeepStrictEqual)(a, b);
|
|
32
|
+
}
|
|
33
|
+
if (declared !== null && typeof declared === 'object') {
|
|
34
|
+
return !(0, node_util_1.isDeepStrictEqual)(declared, stored ?? null);
|
|
35
|
+
}
|
|
36
|
+
// Numeric columns round-trip as strings from the driver — compare as numbers
|
|
37
|
+
// or every declared dial would read as changed on every boot.
|
|
38
|
+
if (typeof declared === 'number') {
|
|
39
|
+
return stored == null || Number(stored) !== declared;
|
|
40
|
+
}
|
|
41
|
+
return declared !== (stored ?? undefined);
|
|
42
|
+
}
|
|
43
|
+
/** The declared fields that differ from the stored row (PATCH-shaped). */
|
|
44
|
+
function diffDeclaredFields(cfg, row) {
|
|
45
|
+
const changed = {};
|
|
46
|
+
for (const field of METADATA_FIELDS) {
|
|
47
|
+
const declared = cfg[field];
|
|
48
|
+
if (declared === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
if (fieldDiffers(field, declared, row)) {
|
|
51
|
+
changed[field] = declared;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return changed;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Roles carrying real configuration (title or form schema) — the candidate
|
|
58
|
+
* set for the startup orphan report. Bare FK-ensured rows are excluded.
|
|
59
|
+
*/
|
|
60
|
+
async function listConfiguredRoles() {
|
|
61
|
+
const pool = (0, db_1.getPool)();
|
|
62
|
+
const { rows } = await pool.query(sql_1.LIST_CONFIGURED_ROLES);
|
|
63
|
+
return rows.map((r) => r.role);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Register one declared role at startup.
|
|
67
|
+
*
|
|
68
|
+
* The role is created if missing. Under code ownership its declared fields
|
|
69
|
+
* are compared against the stored row and written through the versioned
|
|
70
|
+
* PATCH path when they differ — a changed form/metadata schema advances the
|
|
71
|
+
* role's schema version and snapshots the pair; an unchanged declaration is
|
|
72
|
+
* a no-op. Under db ownership the metadata is written exactly once (at
|
|
73
|
+
* creation); afterwards the DB owns the row and drift is warn-logged only.
|
|
74
|
+
* Escalation targets use replace semantics when declared.
|
|
75
|
+
*/
|
|
76
|
+
async function applyRoleConfig(cfg, codeOwned) {
|
|
77
|
+
const created = await (0, index_1.createRole)(cfg.role);
|
|
78
|
+
const pool = (0, db_1.getPool)();
|
|
79
|
+
const { rows } = await pool.query(sql_1.GET_ROLE_ROW, [cfg.role]);
|
|
80
|
+
const row = rows[0];
|
|
81
|
+
const changed = diffDeclaredFields(cfg, row);
|
|
82
|
+
const changedFields = Object.keys(changed);
|
|
83
|
+
const declaredTargets = cfg.escalation_targets != null ? [...cfg.escalation_targets].sort() : null;
|
|
84
|
+
const storedTargets = declaredTargets != null ? await (0, index_1.getEscalationTargets)(cfg.role) : null;
|
|
85
|
+
const targetsDiffer = declaredTargets != null && !(0, node_util_1.isDeepStrictEqual)(declaredTargets, [...storedTargets].sort());
|
|
86
|
+
if (!codeOwned) {
|
|
87
|
+
if (created) {
|
|
88
|
+
// First boot for this role — write the declared metadata once. From
|
|
89
|
+
// here the DB owns the row (the dependents' "only if unconfigured"
|
|
90
|
+
// guard, moved into core).
|
|
91
|
+
if (changedFields.length > 0) {
|
|
92
|
+
await (0, index_1.updateRoleMetadata)(cfg.role, changed);
|
|
93
|
+
}
|
|
94
|
+
if (targetsDiffer)
|
|
95
|
+
await (0, index_1.replaceEscalationTargets)(cfg.role, declaredTargets);
|
|
96
|
+
return 'applied';
|
|
97
|
+
}
|
|
98
|
+
if (changedFields.length > 0 || targetsDiffer) {
|
|
99
|
+
const drifts = [...changedFields, ...(targetsDiffer ? ['escalation_targets'] : [])];
|
|
100
|
+
logger_1.loggerRegistry.warn(`[long-tail] config drift: role ${cfg.role} — ${drifts.join(', ')} differ between code and DB`);
|
|
101
|
+
}
|
|
102
|
+
return 'db-owned';
|
|
103
|
+
}
|
|
104
|
+
if (changedFields.length === 0 && !targetsDiffer)
|
|
105
|
+
return 'unchanged';
|
|
106
|
+
if (changedFields.length > 0) {
|
|
107
|
+
await (0, index_1.updateRoleMetadata)(cfg.role, { ...changed, change_summary: exports.STARTUP_CHANGE_SUMMARY });
|
|
108
|
+
}
|
|
109
|
+
if (targetsDiffer) {
|
|
110
|
+
await (0, index_1.replaceEscalationTargets)(cfg.role, declaredTargets);
|
|
111
|
+
}
|
|
112
|
+
return 'applied';
|
|
113
|
+
}
|
|
@@ -14,6 +14,14 @@ export declare const DELETE_ESCALATION_CHAINS_BY_SOURCE = "\n DELETE FROM lt_co
|
|
|
14
14
|
export declare const CHECK_ESCALATION_CHAIN_EXISTS = "\n SELECT 1\n FROM lt_config_role_escalations\n WHERE source_role = $1 AND target_role = $2";
|
|
15
15
|
export declare const ENSURE_ROLE_EXISTS = "\n INSERT INTO lt_roles (role) VALUES ($1)\n ON CONFLICT DO NOTHING";
|
|
16
16
|
export declare const LIST_ROLES = "\n SELECT role FROM lt_roles ORDER BY role";
|
|
17
|
+
/**
|
|
18
|
+
* Roles carrying real configuration (a title or a form schema). Bare FK rows
|
|
19
|
+
* and membership-only roles are excluded — the startup orphan report uses
|
|
20
|
+
* this so auto-ensured rows never read as drift.
|
|
21
|
+
*/
|
|
22
|
+
export declare const LIST_CONFIGURED_ROLES = "\n SELECT role FROM lt_roles\n WHERE title IS NOT NULL OR form_schema IS NOT NULL\n ORDER BY role";
|
|
23
|
+
/** One role's full metadata row (plus upstream inputs) for startup diffing. */
|
|
24
|
+
export declare const GET_ROLE_ROW = "\n SELECT\n r.role, r.title, r.description, r.form_schema, r.metadata_schema,\n r.properties, r.ops_visible, r.ops_home_default, r.parent_role,\n r.sla_minutes, r.target_per_hour, r.worker_count,\n r.priority_threshold_minutes, r.priority_facet,\n r.entity_facet, r.entity_state_source,\n r.list_schema, r.default_pins, r.enforce_schema,\n r.current_schema_version, r.current_list_schema_version,\n COALESCE((SELECT array_agg(u.upstream_role ORDER BY u.upstream_role)\n FROM lt_role_upstreams u WHERE u.role = r.role), '{}') AS upstream_roles\n FROM lt_roles r\n WHERE r.role = $1";
|
|
17
25
|
export declare const DELETE_ROLE = "\n DELETE FROM lt_roles WHERE role = $1";
|
|
18
26
|
/**
|
|
19
27
|
* PATCH semantics in ONE atomic statement: each column has a boolean
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ─── Escalation chain queries ───────────────────────────────────────────────
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.COUNT_ACTIVE_ESCALATION_REFS = exports.COUNT_WORKFLOW_REFS = exports.COUNT_CHAIN_REFS = exports.COUNT_USER_ROLE_REFS = exports.LIST_ROLES_WITH_DETAILS = exports.GET_ROLE_LIST_SCHEMA_CURRENT = exports.GET_ROLE_LIST_SCHEMA_VERSION = exports.LIST_ROLE_LIST_SCHEMA_VERSIONS = exports.GET_ROLE_SCHEMA_CURRENT = exports.GET_ROLE_SCHEMA_VERSION = exports.LIST_ROLE_SCHEMA_VERSIONS = exports.GET_ROLE_UPSTREAMS = exports.GET_ROLE_PROPERTIES = exports.GET_ROLE_METADATA_SCHEMA = exports.LIST_ENFORCING_ROLES = exports.GET_ROLE_FORM_SCHEMA = exports.UPDATE_ROLE_METADATA = exports.DELETE_ROLE = exports.LIST_ROLES = exports.ENSURE_ROLE_EXISTS = exports.CHECK_ESCALATION_CHAIN_EXISTS = exports.DELETE_ESCALATION_CHAINS_BY_SOURCE = exports.DELETE_ESCALATION_CHAIN = exports.ADD_ESCALATION_CHAIN = exports.INSERT_ESCALATION_CHAIN = exports.GET_ALL_ESCALATION_CHAINS = exports.GET_ESCALATION_TARGETS = void 0;
|
|
4
|
+
exports.COUNT_ACTIVE_ESCALATION_REFS = exports.COUNT_WORKFLOW_REFS = exports.COUNT_CHAIN_REFS = exports.COUNT_USER_ROLE_REFS = exports.LIST_ROLES_WITH_DETAILS = exports.GET_ROLE_LIST_SCHEMA_CURRENT = exports.GET_ROLE_LIST_SCHEMA_VERSION = exports.LIST_ROLE_LIST_SCHEMA_VERSIONS = exports.GET_ROLE_SCHEMA_CURRENT = exports.GET_ROLE_SCHEMA_VERSION = exports.LIST_ROLE_SCHEMA_VERSIONS = exports.GET_ROLE_UPSTREAMS = exports.GET_ROLE_PROPERTIES = exports.GET_ROLE_METADATA_SCHEMA = exports.LIST_ENFORCING_ROLES = exports.GET_ROLE_FORM_SCHEMA = exports.UPDATE_ROLE_METADATA = exports.DELETE_ROLE = exports.GET_ROLE_ROW = exports.LIST_CONFIGURED_ROLES = exports.LIST_ROLES = exports.ENSURE_ROLE_EXISTS = exports.CHECK_ESCALATION_CHAIN_EXISTS = exports.DELETE_ESCALATION_CHAINS_BY_SOURCE = exports.DELETE_ESCALATION_CHAIN = exports.ADD_ESCALATION_CHAIN = exports.INSERT_ESCALATION_CHAIN = exports.GET_ALL_ESCALATION_CHAINS = exports.GET_ESCALATION_TARGETS = void 0;
|
|
5
5
|
exports.GET_ESCALATION_TARGETS = `
|
|
6
6
|
SELECT target_role
|
|
7
7
|
FROM lt_config_role_escalations
|
|
@@ -47,6 +47,29 @@ exports.ENSURE_ROLE_EXISTS = `
|
|
|
47
47
|
ON CONFLICT DO NOTHING`;
|
|
48
48
|
exports.LIST_ROLES = `
|
|
49
49
|
SELECT role FROM lt_roles ORDER BY role`;
|
|
50
|
+
/**
|
|
51
|
+
* Roles carrying real configuration (a title or a form schema). Bare FK rows
|
|
52
|
+
* and membership-only roles are excluded — the startup orphan report uses
|
|
53
|
+
* this so auto-ensured rows never read as drift.
|
|
54
|
+
*/
|
|
55
|
+
exports.LIST_CONFIGURED_ROLES = `
|
|
56
|
+
SELECT role FROM lt_roles
|
|
57
|
+
WHERE title IS NOT NULL OR form_schema IS NOT NULL
|
|
58
|
+
ORDER BY role`;
|
|
59
|
+
/** One role's full metadata row (plus upstream inputs) for startup diffing. */
|
|
60
|
+
exports.GET_ROLE_ROW = `
|
|
61
|
+
SELECT
|
|
62
|
+
r.role, r.title, r.description, r.form_schema, r.metadata_schema,
|
|
63
|
+
r.properties, r.ops_visible, r.ops_home_default, r.parent_role,
|
|
64
|
+
r.sla_minutes, r.target_per_hour, r.worker_count,
|
|
65
|
+
r.priority_threshold_minutes, r.priority_facet,
|
|
66
|
+
r.entity_facet, r.entity_state_source,
|
|
67
|
+
r.list_schema, r.default_pins, r.enforce_schema,
|
|
68
|
+
r.current_schema_version, r.current_list_schema_version,
|
|
69
|
+
COALESCE((SELECT array_agg(u.upstream_role ORDER BY u.upstream_role)
|
|
70
|
+
FROM lt_role_upstreams u WHERE u.role = r.role), '{}') AS upstream_roles
|
|
71
|
+
FROM lt_roles r
|
|
72
|
+
WHERE r.role = $1`;
|
|
50
73
|
exports.DELETE_ROLE = `
|
|
51
74
|
DELETE FROM lt_roles WHERE role = $1`;
|
|
52
75
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { listScanSchemes, getScanScheme, listScanRules, getScanRule, } from './read';
|
|
2
|
-
export { upsertScanScheme, deleteScanScheme, upsertScanRule, deleteScanRule, seedScanScheme, seedScanRule, type ScanSchemeInput, type ScanRuleInput, } from './write';
|
|
2
|
+
export { upsertScanScheme, deleteScanScheme, upsertScanRule, deleteScanRule, seedScanScheme, seedScanRule, applyScanScheme, applyScanRule, type ScanSchemeInput, type ScanRuleInput, } from './write';
|
|
3
3
|
export { parseScanCode, interpolateScanTemplate, type ScanParseResult, type ScanParseFailure, type ScanTemplateContext, } from './parse';
|
|
4
4
|
export { assertValidScheme, assertValidSteps } from './validate';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assertValidSteps = exports.assertValidScheme = exports.interpolateScanTemplate = exports.parseScanCode = exports.seedScanRule = exports.seedScanScheme = exports.deleteScanRule = exports.upsertScanRule = exports.deleteScanScheme = exports.upsertScanScheme = exports.getScanRule = exports.listScanRules = exports.getScanScheme = exports.listScanSchemes = void 0;
|
|
3
|
+
exports.assertValidSteps = exports.assertValidScheme = exports.interpolateScanTemplate = exports.parseScanCode = exports.applyScanRule = exports.applyScanScheme = exports.seedScanRule = exports.seedScanScheme = exports.deleteScanRule = exports.upsertScanRule = exports.deleteScanScheme = exports.upsertScanScheme = exports.getScanRule = exports.listScanRules = exports.getScanScheme = exports.listScanSchemes = void 0;
|
|
4
4
|
var read_1 = require("./read");
|
|
5
5
|
Object.defineProperty(exports, "listScanSchemes", { enumerable: true, get: function () { return read_1.listScanSchemes; } });
|
|
6
6
|
Object.defineProperty(exports, "getScanScheme", { enumerable: true, get: function () { return read_1.getScanScheme; } });
|
|
@@ -13,6 +13,8 @@ Object.defineProperty(exports, "upsertScanRule", { enumerable: true, get: functi
|
|
|
13
13
|
Object.defineProperty(exports, "deleteScanRule", { enumerable: true, get: function () { return write_1.deleteScanRule; } });
|
|
14
14
|
Object.defineProperty(exports, "seedScanScheme", { enumerable: true, get: function () { return write_1.seedScanScheme; } });
|
|
15
15
|
Object.defineProperty(exports, "seedScanRule", { enumerable: true, get: function () { return write_1.seedScanRule; } });
|
|
16
|
+
Object.defineProperty(exports, "applyScanScheme", { enumerable: true, get: function () { return write_1.applyScanScheme; } });
|
|
17
|
+
Object.defineProperty(exports, "applyScanRule", { enumerable: true, get: function () { return write_1.applyScanRule; } });
|
|
16
18
|
var parse_1 = require("./parse");
|
|
17
19
|
Object.defineProperty(exports, "parseScanCode", { enumerable: true, get: function () { return parse_1.parseScanCode; } });
|
|
18
20
|
Object.defineProperty(exports, "interpolateScanTemplate", { enumerable: true, get: function () { return parse_1.interpolateScanTemplate; } });
|
|
@@ -8,3 +8,10 @@ export declare const UPSERT_ACTION = "INSERT INTO lt_config_scan_actions\n (sch
|
|
|
8
8
|
export declare const DELETE_ACTION = "DELETE FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2";
|
|
9
9
|
export declare const SEED_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO NOTHING";
|
|
10
10
|
export declare const SEED_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO NOTHING";
|
|
11
|
+
/**
|
|
12
|
+
* Apply — same column set as the upsert, guarded by IS DISTINCT FROM so an
|
|
13
|
+
* unchanged declaration is a zero-row no-op. `(xmax = 0)` distinguishes
|
|
14
|
+
* insert from update. jsonb columns compare content-wise in SQL.
|
|
15
|
+
*/
|
|
16
|
+
export declare const APPLY_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n kind = EXCLUDED.kind,\n grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,\n grant_max_uses = EXCLUDED.grant_max_uses,\n enabled = EXCLUDED.enabled,\n updated_at = NOW()\nWHERE (lt_config_scan_schemes.name, lt_config_scan_schemes.description,\n lt_config_scan_schemes.target_facet, lt_config_scan_schemes.encoding,\n lt_config_scan_schemes.delimiter, lt_config_scan_schemes.target_length,\n lt_config_scan_schemes.kind, lt_config_scan_schemes.grant_ttl_seconds,\n lt_config_scan_schemes.grant_max_uses, lt_config_scan_schemes.enabled)\n IS DISTINCT FROM\n (EXCLUDED.name, EXCLUDED.description, EXCLUDED.target_facet,\n EXCLUDED.encoding, EXCLUDED.delimiter, EXCLUDED.target_length,\n EXCLUDED.kind, EXCLUDED.grant_ttl_seconds, EXCLUDED.grant_max_uses,\n EXCLUDED.enabled)\nRETURNING (xmax = 0) AS inserted";
|
|
17
|
+
export declare const APPLY_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO UPDATE SET\n name = EXCLUDED.name,\n steps = EXCLUDED.steps,\n fallback = EXCLUDED.fallback,\n not_primed = EXCLUDED.not_primed,\n enabled = EXCLUDED.enabled,\n updated_at = NOW()\nWHERE (lt_config_scan_actions.name, lt_config_scan_actions.steps,\n lt_config_scan_actions.fallback, lt_config_scan_actions.not_primed,\n lt_config_scan_actions.enabled)\n IS DISTINCT FROM\n (EXCLUDED.name, EXCLUDED.steps, EXCLUDED.fallback,\n EXCLUDED.not_primed, EXCLUDED.enabled)\nRETURNING (xmax = 0) AS inserted";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Read queries //
|
|
4
4
|
// ------------------------------------------------------------------ //
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SEED_ACTION = exports.SEED_SCHEME = exports.DELETE_ACTION = exports.UPSERT_ACTION = exports.DELETE_SCHEME = exports.UPSERT_SCHEME = exports.GET_ACTION = exports.LIST_ACTIONS = exports.GET_SCHEME = exports.LIST_SCHEMES = void 0;
|
|
6
|
+
exports.APPLY_ACTION = exports.APPLY_SCHEME = exports.SEED_ACTION = exports.SEED_SCHEME = exports.DELETE_ACTION = exports.UPSERT_ACTION = exports.DELETE_SCHEME = exports.UPSERT_SCHEME = exports.GET_ACTION = exports.LIST_ACTIONS = exports.GET_SCHEME = exports.LIST_SCHEMES = void 0;
|
|
7
7
|
exports.LIST_SCHEMES = `\
|
|
8
8
|
SELECT * FROM lt_config_scan_schemes ORDER BY version`;
|
|
9
9
|
exports.GET_SCHEME = `\
|
|
@@ -61,3 +61,57 @@ INSERT INTO lt_config_scan_actions
|
|
|
61
61
|
(scheme_version, category, name, steps, fallback, not_primed, enabled)
|
|
62
62
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
63
63
|
ON CONFLICT (scheme_version, category) DO NOTHING`;
|
|
64
|
+
// ------------------------------------------------------------------ //
|
|
65
|
+
// Apply (code-owned startup pass — code is source of truth) //
|
|
66
|
+
// ------------------------------------------------------------------ //
|
|
67
|
+
/**
|
|
68
|
+
* Apply — same column set as the upsert, guarded by IS DISTINCT FROM so an
|
|
69
|
+
* unchanged declaration is a zero-row no-op. `(xmax = 0)` distinguishes
|
|
70
|
+
* insert from update. jsonb columns compare content-wise in SQL.
|
|
71
|
+
*/
|
|
72
|
+
exports.APPLY_SCHEME = `\
|
|
73
|
+
INSERT INTO lt_config_scan_schemes
|
|
74
|
+
(version, name, description, target_facet, encoding, delimiter, target_length,
|
|
75
|
+
kind, grant_ttl_seconds, grant_max_uses, enabled)
|
|
76
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
77
|
+
ON CONFLICT (version) DO UPDATE SET
|
|
78
|
+
name = EXCLUDED.name,
|
|
79
|
+
description = EXCLUDED.description,
|
|
80
|
+
target_facet = EXCLUDED.target_facet,
|
|
81
|
+
encoding = EXCLUDED.encoding,
|
|
82
|
+
delimiter = EXCLUDED.delimiter,
|
|
83
|
+
target_length = EXCLUDED.target_length,
|
|
84
|
+
kind = EXCLUDED.kind,
|
|
85
|
+
grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,
|
|
86
|
+
grant_max_uses = EXCLUDED.grant_max_uses,
|
|
87
|
+
enabled = EXCLUDED.enabled,
|
|
88
|
+
updated_at = NOW()
|
|
89
|
+
WHERE (lt_config_scan_schemes.name, lt_config_scan_schemes.description,
|
|
90
|
+
lt_config_scan_schemes.target_facet, lt_config_scan_schemes.encoding,
|
|
91
|
+
lt_config_scan_schemes.delimiter, lt_config_scan_schemes.target_length,
|
|
92
|
+
lt_config_scan_schemes.kind, lt_config_scan_schemes.grant_ttl_seconds,
|
|
93
|
+
lt_config_scan_schemes.grant_max_uses, lt_config_scan_schemes.enabled)
|
|
94
|
+
IS DISTINCT FROM
|
|
95
|
+
(EXCLUDED.name, EXCLUDED.description, EXCLUDED.target_facet,
|
|
96
|
+
EXCLUDED.encoding, EXCLUDED.delimiter, EXCLUDED.target_length,
|
|
97
|
+
EXCLUDED.kind, EXCLUDED.grant_ttl_seconds, EXCLUDED.grant_max_uses,
|
|
98
|
+
EXCLUDED.enabled)
|
|
99
|
+
RETURNING (xmax = 0) AS inserted`;
|
|
100
|
+
exports.APPLY_ACTION = `\
|
|
101
|
+
INSERT INTO lt_config_scan_actions
|
|
102
|
+
(scheme_version, category, name, steps, fallback, not_primed, enabled)
|
|
103
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
104
|
+
ON CONFLICT (scheme_version, category) DO UPDATE SET
|
|
105
|
+
name = EXCLUDED.name,
|
|
106
|
+
steps = EXCLUDED.steps,
|
|
107
|
+
fallback = EXCLUDED.fallback,
|
|
108
|
+
not_primed = EXCLUDED.not_primed,
|
|
109
|
+
enabled = EXCLUDED.enabled,
|
|
110
|
+
updated_at = NOW()
|
|
111
|
+
WHERE (lt_config_scan_actions.name, lt_config_scan_actions.steps,
|
|
112
|
+
lt_config_scan_actions.fallback, lt_config_scan_actions.not_primed,
|
|
113
|
+
lt_config_scan_actions.enabled)
|
|
114
|
+
IS DISTINCT FROM
|
|
115
|
+
(EXCLUDED.name, EXCLUDED.steps, EXCLUDED.fallback,
|
|
116
|
+
EXCLUDED.not_primed, EXCLUDED.enabled)
|
|
117
|
+
RETURNING (xmax = 0) AS inserted`;
|
|
@@ -28,3 +28,11 @@ export declare function deleteScanRule(schemeVersion: number, category: string):
|
|
|
28
28
|
/** Insert-if-absent seeding — DB is the source of truth, never overwrite. */
|
|
29
29
|
export declare function seedScanScheme(input: ScanSchemeInput): Promise<boolean>;
|
|
30
30
|
export declare function seedScanRule(input: ScanRuleInput): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Apply a scheme declaration at startup (code is source of truth). Same
|
|
33
|
+
* validation as the upsert; the IS DISTINCT FROM guard makes an unchanged
|
|
34
|
+
* declaration a zero-row no-op.
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyScanScheme(input: ScanSchemeInput): Promise<'applied' | 'unchanged'>;
|
|
37
|
+
/** Apply a rule declaration at startup (code is source of truth). */
|
|
38
|
+
export declare function applyScanRule(input: ScanRuleInput): Promise<'applied' | 'unchanged'>;
|
|
@@ -6,6 +6,8 @@ exports.upsertScanRule = upsertScanRule;
|
|
|
6
6
|
exports.deleteScanRule = deleteScanRule;
|
|
7
7
|
exports.seedScanScheme = seedScanScheme;
|
|
8
8
|
exports.seedScanRule = seedScanRule;
|
|
9
|
+
exports.applyScanScheme = applyScanScheme;
|
|
10
|
+
exports.applyScanRule = applyScanRule;
|
|
9
11
|
const db_1 = require("../../lib/db");
|
|
10
12
|
const types_1 = require("../../types");
|
|
11
13
|
const sql_1 = require("./sql");
|
|
@@ -55,7 +57,8 @@ async function deleteScanScheme(version) {
|
|
|
55
57
|
const { rowCount } = await (0, db_1.getPool)().query(sql_1.DELETE_SCHEME, [version]);
|
|
56
58
|
return (rowCount ?? 0) > 0;
|
|
57
59
|
}
|
|
58
|
-
|
|
60
|
+
/** Shared rule-input validation — the upsert and startup-apply paths enforce the same contract. */
|
|
61
|
+
async function assertValidRuleInput(input) {
|
|
59
62
|
if (!/^[0-9]$/.test(input.category)) {
|
|
60
63
|
throw new Error('category must be a single digit (0-9)');
|
|
61
64
|
}
|
|
@@ -65,6 +68,9 @@ async function upsertScanRule(input) {
|
|
|
65
68
|
if (input.steps.length === 0 && !input.fallback?.markdown && !input.fallback?.route) {
|
|
66
69
|
throw new Error('a rule needs at least one step or a fallback');
|
|
67
70
|
}
|
|
71
|
+
}
|
|
72
|
+
async function upsertScanRule(input) {
|
|
73
|
+
await assertValidRuleInput(input);
|
|
68
74
|
const { rows } = await (0, db_1.getPool)().query(sql_1.UPSERT_ACTION, ruleParams(input));
|
|
69
75
|
return rows[0];
|
|
70
76
|
}
|
|
@@ -83,3 +89,19 @@ async function seedScanRule(input) {
|
|
|
83
89
|
const { rowCount } = await (0, db_1.getPool)().query(sql_1.SEED_ACTION, ruleParams(input));
|
|
84
90
|
return (rowCount ?? 0) > 0;
|
|
85
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Apply a scheme declaration at startup (code is source of truth). Same
|
|
94
|
+
* validation as the upsert; the IS DISTINCT FROM guard makes an unchanged
|
|
95
|
+
* declaration a zero-row no-op.
|
|
96
|
+
*/
|
|
97
|
+
async function applyScanScheme(input) {
|
|
98
|
+
(0, validate_1.assertValidScheme)(input);
|
|
99
|
+
const { rowCount } = await (0, db_1.getPool)().query(sql_1.APPLY_SCHEME, schemeParams(input));
|
|
100
|
+
return (rowCount ?? 0) > 0 ? 'applied' : 'unchanged';
|
|
101
|
+
}
|
|
102
|
+
/** Apply a rule declaration at startup (code is source of truth). */
|
|
103
|
+
async function applyScanRule(input) {
|
|
104
|
+
await assertValidRuleInput(input);
|
|
105
|
+
const { rowCount } = await (0, db_1.getPool)().query(sql_1.APPLY_ACTION, ruleParams(input));
|
|
106
|
+
return (rowCount ?? 0) > 0 ? 'applied' : 'unchanged';
|
|
107
|
+
}
|
|
@@ -20,6 +20,8 @@ export interface TopicSubscriber {
|
|
|
20
20
|
topic: string;
|
|
21
21
|
reaction_type: string;
|
|
22
22
|
}
|
|
23
|
+
/** Config-declared topic names — the startup orphan report's candidate set. */
|
|
24
|
+
export declare function listConfigTopicNames(): Promise<string[]>;
|
|
23
25
|
export declare function listTopics(filters?: {
|
|
24
26
|
category?: string;
|
|
25
27
|
search?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listConfigTopicNames = listConfigTopicNames;
|
|
3
4
|
exports.listTopics = listTopics;
|
|
4
5
|
exports.getTopic = getTopic;
|
|
5
6
|
exports.createTopic = createTopic;
|
|
@@ -10,6 +11,12 @@ exports.seedTopic = seedTopic;
|
|
|
10
11
|
exports.resetTopic = resetTopic;
|
|
11
12
|
const db_1 = require("../../lib/db");
|
|
12
13
|
const sql_1 = require("./sql");
|
|
14
|
+
/** Config-declared topic names — the startup orphan report's candidate set. */
|
|
15
|
+
async function listConfigTopicNames() {
|
|
16
|
+
const pool = (0, db_1.getPool)();
|
|
17
|
+
const { rows } = await pool.query(sql_1.LIST_CONFIG_TOPIC_NAMES);
|
|
18
|
+
return rows.map((r) => r.topic);
|
|
19
|
+
}
|
|
13
20
|
async function listTopics(filters = {}) {
|
|
14
21
|
const pool = (0, db_1.getPool)();
|
|
15
22
|
const limit = filters.limit ?? 50;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare const LIST_TOPICS = "\n SELECT t.*,\n COALESCE(s.sub_count, 0)::int AS subscriber_count\n FROM lt_topic_catalog t\n LEFT JOIN LATERAL (\n SELECT COUNT(*)::int AS sub_count\n FROM lt_agent_subscriptions\n WHERE enabled = true\n AND (\n topic = t.topic\n OR t.topic LIKE REPLACE(REPLACE(topic, '*', '%'), '>', '%')\n )\n ) s ON true\n WHERE ($1::text IS NULL OR t.category = $1)\n AND ($2::text IS NULL OR t.topic ILIKE '%' || $2 || '%' OR t.description ILIKE '%' || $2 || '%')\n ORDER BY t.category, t.topic\n LIMIT $3 OFFSET $4\n";
|
|
2
2
|
export declare const COUNT_TOPICS = "\n SELECT COUNT(*)::int AS total FROM lt_topic_catalog\n WHERE ($1::text IS NULL OR category = $1)\n AND ($2::text IS NULL OR topic ILIKE '%' || $2 || '%' OR description ILIKE '%' || $2 || '%')\n";
|
|
3
|
+
/** Config-declared topic names — the startup orphan report's candidate set. */
|
|
4
|
+
export declare const LIST_CONFIG_TOPIC_NAMES = "\n SELECT topic FROM lt_topic_catalog WHERE source = 'config' ORDER BY topic\n";
|
|
3
5
|
export declare const GET_TOPIC = "\n SELECT * FROM lt_topic_catalog WHERE topic = $1\n";
|
|
4
6
|
export declare const INSERT_TOPIC = "\n INSERT INTO lt_topic_catalog\n (topic, description, category, payload_schema, example_payload, source, tags)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n RETURNING *\n";
|
|
5
7
|
export declare const UPDATE_TOPIC = "\n UPDATE lt_topic_catalog SET\n description = COALESCE($2, description),\n category = COALESCE($3, category),\n payload_schema = COALESCE($4, payload_schema),\n example_payload = COALESCE($5, example_payload),\n tags = COALESCE($6, tags)\n WHERE topic = $1\n RETURNING *\n";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LIST_SUBSCRIBERS = exports.RESET_TOPIC = exports.SEED_TOPIC = exports.UPSERT_ON_PUBLISH = exports.DELETE_TOPIC = exports.UPDATE_TOPIC = exports.INSERT_TOPIC = exports.GET_TOPIC = exports.COUNT_TOPICS = exports.LIST_TOPICS = void 0;
|
|
3
|
+
exports.LIST_SUBSCRIBERS = exports.RESET_TOPIC = exports.SEED_TOPIC = exports.UPSERT_ON_PUBLISH = exports.DELETE_TOPIC = exports.UPDATE_TOPIC = exports.INSERT_TOPIC = exports.GET_TOPIC = exports.LIST_CONFIG_TOPIC_NAMES = exports.COUNT_TOPICS = exports.LIST_TOPICS = void 0;
|
|
4
4
|
exports.LIST_TOPICS = `
|
|
5
5
|
SELECT t.*,
|
|
6
6
|
COALESCE(s.sub_count, 0)::int AS subscriber_count
|
|
@@ -24,6 +24,10 @@ exports.COUNT_TOPICS = `
|
|
|
24
24
|
WHERE ($1::text IS NULL OR category = $1)
|
|
25
25
|
AND ($2::text IS NULL OR topic ILIKE '%' || $2 || '%' OR description ILIKE '%' || $2 || '%')
|
|
26
26
|
`;
|
|
27
|
+
/** Config-declared topic names — the startup orphan report's candidate set. */
|
|
28
|
+
exports.LIST_CONFIG_TOPIC_NAMES = `
|
|
29
|
+
SELECT topic FROM lt_topic_catalog WHERE source = 'config' ORDER BY topic
|
|
30
|
+
`;
|
|
27
31
|
exports.GET_TOPIC = `
|
|
28
32
|
SELECT * FROM lt_topic_catalog WHERE topic = $1
|
|
29
33
|
`;
|
|
@@ -2,6 +2,7 @@ import type { LTTopicConfig } from '../../types';
|
|
|
2
2
|
export declare function seedSystemTopics(): Promise<void>;
|
|
3
3
|
/**
|
|
4
4
|
* Seed user-declared topics from startConfig.topics[].
|
|
5
|
-
*
|
|
5
|
+
* Ownership per entry: `reset ?? defaultReset` — code-owned topics are
|
|
6
|
+
* overwritten from config on every boot; db-owned topics are insert-if-absent.
|
|
6
7
|
*/
|
|
7
|
-
export declare function seedConfigTopics(topics: LTTopicConfig[]): Promise<void>;
|
|
8
|
+
export declare function seedConfigTopics(topics: LTTopicConfig[], defaultReset?: boolean): Promise<void>;
|
|
@@ -314,9 +314,10 @@ async function seedSystemTopics() {
|
|
|
314
314
|
}
|
|
315
315
|
/**
|
|
316
316
|
* Seed user-declared topics from startConfig.topics[].
|
|
317
|
-
*
|
|
317
|
+
* Ownership per entry: `reset ?? defaultReset` — code-owned topics are
|
|
318
|
+
* overwritten from config on every boot; db-owned topics are insert-if-absent.
|
|
318
319
|
*/
|
|
319
|
-
async function seedConfigTopics(topics) {
|
|
320
|
+
async function seedConfigTopics(topics, defaultReset = false) {
|
|
320
321
|
for (const def of topics) {
|
|
321
322
|
try {
|
|
322
323
|
const payload = {
|
|
@@ -328,7 +329,7 @@ async function seedConfigTopics(topics) {
|
|
|
328
329
|
source: 'config',
|
|
329
330
|
tags: def.tags ?? [],
|
|
330
331
|
};
|
|
331
|
-
if (def.reset) {
|
|
332
|
+
if (def.reset ?? defaultReset) {
|
|
332
333
|
await (0, index_1.resetTopic)(payload);
|
|
333
334
|
logger_1.loggerRegistry.info(`[long-tail] topic reset: ${def.topic} (config)`);
|
|
334
335
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { CreateUserInput, UpdateUserInput, VALID_ROLE_TYPES } from './types';
|
|
2
2
|
export { createUser, getUser, getUserByExternalId, getUserByEmail, getUserByMetadataValue, updateUser, deleteUser, listUsers, } from './crud';
|
|
3
|
-
export { isValidRoleType, addUserRole, removeUserRole, getUserRoles, hasRole, hasRoleType, } from './roles';
|
|
3
|
+
export { isValidRoleType, addUserRole, grantRoleIfAbsent, removeUserRole, getUserRoles, hasRole, hasRoleType, } from './roles';
|
|
4
4
|
export { isSuperAdmin, isGroupAdmin, canManageRole, hasGlobalEscalationAccess, hasRolesAsAdmin, getRoleScope, getRoleWriteScope } from './rbac';
|
|
5
5
|
export { READ_SCOPES, WRITE_SCOPES, DEFAULT_READ_SCOPE, DEFAULT_WRITE_SCOPE, isValidReadScope, isValidWriteScope, isValidScopePair, effectiveScope, } from './scope';
|
|
6
6
|
export { verifyPassword } from './auth';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PREFERENCES_MAX_BYTES = exports.patchPreferences = exports.getPreferences = exports.seedAdmin = exports.verifyPassword = exports.effectiveScope = exports.isValidScopePair = exports.isValidWriteScope = exports.isValidReadScope = exports.DEFAULT_WRITE_SCOPE = exports.DEFAULT_READ_SCOPE = exports.WRITE_SCOPES = exports.READ_SCOPES = exports.getRoleWriteScope = exports.getRoleScope = exports.hasRolesAsAdmin = exports.hasGlobalEscalationAccess = exports.canManageRole = exports.isGroupAdmin = exports.isSuperAdmin = exports.hasRoleType = exports.hasRole = exports.getUserRoles = exports.removeUserRole = exports.addUserRole = exports.isValidRoleType = exports.listUsers = exports.deleteUser = exports.updateUser = exports.getUserByMetadataValue = exports.getUserByEmail = exports.getUserByExternalId = exports.getUser = exports.createUser = exports.VALID_ROLE_TYPES = void 0;
|
|
3
|
+
exports.PREFERENCES_MAX_BYTES = exports.patchPreferences = exports.getPreferences = exports.seedAdmin = exports.verifyPassword = exports.effectiveScope = exports.isValidScopePair = exports.isValidWriteScope = exports.isValidReadScope = exports.DEFAULT_WRITE_SCOPE = exports.DEFAULT_READ_SCOPE = exports.WRITE_SCOPES = exports.READ_SCOPES = exports.getRoleWriteScope = exports.getRoleScope = exports.hasRolesAsAdmin = exports.hasGlobalEscalationAccess = exports.canManageRole = exports.isGroupAdmin = exports.isSuperAdmin = exports.hasRoleType = exports.hasRole = exports.getUserRoles = exports.removeUserRole = exports.grantRoleIfAbsent = exports.addUserRole = exports.isValidRoleType = exports.listUsers = exports.deleteUser = exports.updateUser = exports.getUserByMetadataValue = exports.getUserByEmail = exports.getUserByExternalId = exports.getUser = exports.createUser = exports.VALID_ROLE_TYPES = void 0;
|
|
4
4
|
var types_1 = require("./types");
|
|
5
5
|
Object.defineProperty(exports, "VALID_ROLE_TYPES", { enumerable: true, get: function () { return types_1.VALID_ROLE_TYPES; } });
|
|
6
6
|
var crud_1 = require("./crud");
|
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "listUsers", { enumerable: true, get: function ()
|
|
|
15
15
|
var roles_1 = require("./roles");
|
|
16
16
|
Object.defineProperty(exports, "isValidRoleType", { enumerable: true, get: function () { return roles_1.isValidRoleType; } });
|
|
17
17
|
Object.defineProperty(exports, "addUserRole", { enumerable: true, get: function () { return roles_1.addUserRole; } });
|
|
18
|
+
Object.defineProperty(exports, "grantRoleIfAbsent", { enumerable: true, get: function () { return roles_1.grantRoleIfAbsent; } });
|
|
18
19
|
Object.defineProperty(exports, "removeUserRole", { enumerable: true, get: function () { return roles_1.removeUserRole; } });
|
|
19
20
|
Object.defineProperty(exports, "getUserRoles", { enumerable: true, get: function () { return roles_1.getUserRoles; } });
|
|
20
21
|
Object.defineProperty(exports, "hasRole", { enumerable: true, get: function () { return roles_1.hasRole; } });
|
|
@@ -6,6 +6,14 @@ export interface RoleScopeInput {
|
|
|
6
6
|
write_scope?: LTWriteScope;
|
|
7
7
|
}
|
|
8
8
|
export declare function addUserRole(userId: string, role: string, type: LTRoleType, scope?: RoleScopeInput): Promise<LTUserRole>;
|
|
9
|
+
/**
|
|
10
|
+
* Grant a role ONLY when the user does not already hold it — the scope-safe
|
|
11
|
+
* add for sync paths (SSO provisioning, claim-time provisioning). An existing
|
|
12
|
+
* grant is never touched: identity sync adds missing memberships, it never
|
|
13
|
+
* mutates the type/scope/provenance an admin set. Returns the inserted row, or
|
|
14
|
+
* null when the membership already existed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function grantRoleIfAbsent(userId: string, role: string, type: LTRoleType, scope?: RoleScopeInput): Promise<LTUserRole | null>;
|
|
9
17
|
export declare function removeUserRole(userId: string, role: string): Promise<boolean>;
|
|
10
18
|
export declare function getUserRoles(userId: string): Promise<LTUserRole[]>;
|
|
11
19
|
export declare function hasRole(userId: string, role: string): Promise<boolean>;
|