@oneuptime/common 12.0.5 → 12.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/Models/DatabaseModels/AIRun.ts +33 -0
  2. package/Models/DatabaseModels/DataSource.ts +744 -0
  3. package/Models/DatabaseModels/Index.ts +3 -0
  4. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
  5. package/Models/DatabaseModels/User.ts +2 -0
  6. package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
  7. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
  8. package/Models/DatabaseModels/UserSession.ts +2 -0
  9. package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
  10. package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
  11. package/Server/API/AIInsightAPI.ts +47 -4
  12. package/Server/API/AIInvestigationAPI.ts +25 -0
  13. package/Server/API/DashboardAPI.ts +176 -492
  14. package/Server/API/DataSourceAPI.ts +268 -0
  15. package/Server/API/StatusPageAPI.ts +11 -1
  16. package/Server/API/UserAPI.ts +119 -0
  17. package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  22. package/Server/Infrastructure/Queue.ts +26 -0
  23. package/Server/Infrastructure/QueueWorker.ts +17 -0
  24. package/Server/Middleware/TelemetryIngest.ts +8 -3
  25. package/Server/Services/AIInsightService.ts +132 -12
  26. package/Server/Services/AIRunService.ts +34 -0
  27. package/Server/Services/AIService.ts +17 -2
  28. package/Server/Services/AlertService.ts +38 -32
  29. package/Server/Services/AnalyticsDatabaseService.ts +8 -4
  30. package/Server/Services/DataSourceService.ts +200 -0
  31. package/Server/Services/HostService.ts +92 -0
  32. package/Server/Services/IncidentService.ts +45 -0
  33. package/Server/Services/Index.ts +2 -0
  34. package/Server/Services/MonitorService.ts +49 -0
  35. package/Server/Services/MonitorStatusService.ts +166 -0
  36. package/Server/Services/OpenTelemetryIngestService.ts +255 -184
  37. package/Server/Services/RumSessionPinService.ts +7 -21
  38. package/Server/Services/StatusPageSubscriberService.ts +13 -0
  39. package/Server/Services/UserService.ts +280 -9
  40. package/Server/Static/Vendor/README.md +62 -0
  41. package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
  42. package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
  43. package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
  44. package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
  45. package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
  46. package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
  47. package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
  48. package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
  49. package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
  50. package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
  51. package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
  52. package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
  53. package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
  54. package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
  55. package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
  56. package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
  57. package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
  58. package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
  59. package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
  60. package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
  61. package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
  62. package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
  63. package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
  64. package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
  65. package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
  66. package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
  67. package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
  68. package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
  69. package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
  70. package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
  71. package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
  72. package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
  73. package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
  74. package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
  75. package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
  76. package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
  77. package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
  78. package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
  79. package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
  80. package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
  81. package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
  82. package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
  83. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
  84. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
  85. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
  86. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
  90. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
  91. package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
  92. package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
  93. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
  94. package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
  95. package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
  96. package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
  97. package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
  98. package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
  99. package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
  100. package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
  101. package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
  102. package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
  103. package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
  104. package/Server/Utils/DataSource/EgressGuard.ts +446 -0
  105. package/Server/Utils/DataSource/HttpFetch.ts +221 -0
  106. package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
  107. package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
  108. package/Server/Utils/DataSource/Types.ts +93 -0
  109. package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
  110. package/Server/Utils/InProcessMemo.ts +141 -0
  111. package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
  112. package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
  113. package/Server/Utils/Monitor/MonitorResource.ts +14 -0
  114. package/Server/Utils/Response.ts +12 -1
  115. package/Server/Utils/SSRFProtection.ts +237 -0
  116. package/Server/Utils/StartServer.ts +8 -0
  117. package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
  118. package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
  119. package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
  120. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
  121. package/Server/Utils/Telemetry/Telemetry.ts +112 -1
  122. package/Server/Utils/Telemetry.ts +104 -3
  123. package/Server/Utils/VendorAssets.ts +165 -0
  124. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
  125. package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
  126. package/Server/Views/Partials/Head.ejs +21 -7
  127. package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
  128. package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
  129. package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
  130. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
  131. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
  132. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
  133. package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
  134. package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
  135. package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
  136. package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
  137. package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
  138. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
  139. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
  140. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
  141. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
  142. package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
  143. package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
  144. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
  145. package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
  146. package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
  147. package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
  148. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
  149. package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
  150. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
  151. package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
  152. package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
  153. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
  154. package/Tests/Server/Services/AIInsightService.test.ts +266 -11
  155. package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
  156. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
  157. package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
  158. package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
  159. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
  160. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
  161. package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
  162. package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
  163. package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
  164. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
  165. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
  166. package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
  167. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
  168. package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
  169. package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
  170. package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
  171. package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
  172. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
  173. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
  174. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
  175. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
  176. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
  177. package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
  178. package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
  179. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
  180. package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
  181. package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
  182. package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
  183. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
  184. package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
  185. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
  186. package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
  187. package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
  188. package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
  189. package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
  190. package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
  191. package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
  192. package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
  193. package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
  194. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
  195. package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
  196. package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
  197. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
  198. package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
  199. package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
  200. package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
  201. package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
  202. package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
  203. package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
  205. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
  206. package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
  207. package/Tests/Server/Utils/Telemetry.test.ts +87 -0
  208. package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
  209. package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
  210. package/Tests/Server/Views/OfflineRender.test.ts +297 -0
  211. package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
  212. package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
  213. package/Tests/Types/Password.test.ts +363 -0
  214. package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
  215. package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
  216. package/Tests/UI/Components/Modal.test.tsx +281 -1
  217. package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
  218. package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
  219. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
  220. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  221. package/Tests/Utils/Analytics.test.ts +23 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
  223. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
  224. package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
  225. package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
  226. package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
  227. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
  228. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
  229. package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
  230. package/Types/AI/AIInsightEvidence.ts +6 -0
  231. package/Types/Analytics/RevenueEvent.ts +31 -0
  232. package/Types/Dashboard/DashboardComponentType.ts +31 -0
  233. package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
  234. package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
  235. package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
  236. package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
  237. package/Types/DataSource/DataSourceLimits.ts +62 -0
  238. package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
  239. package/Types/DataSource/DataSourceTableResult.ts +38 -0
  240. package/Types/DataSource/DataSourceType.ts +213 -0
  241. package/Types/Date.ts +43 -3
  242. package/Types/Password.ts +64 -0
  243. package/Types/Permission.ts +46 -0
  244. package/Types/UserAuthenticationStatus.ts +34 -0
  245. package/UI/Components/Button/Button.tsx +1 -1
  246. package/UI/Components/ErrorBoundary.tsx +459 -108
  247. package/UI/Components/Icon/Icon.tsx +10 -9
  248. package/UI/Components/Modal/ConfirmModal.tsx +6 -1
  249. package/UI/Components/Modal/Modal.tsx +267 -35
  250. package/UI/Components/Modal/ModalFooter.tsx +6 -1
  251. package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
  252. package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
  253. package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
  254. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
  255. package/UI/Components/StatusPage/ResourceList.tsx +570 -0
  256. package/UI/Styles/Theme.css +18 -0
  257. package/UI/Utils/API/RequestOptions.ts +7 -0
  258. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
  259. package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
  260. package/UI/Utils/TestDataSource.ts +61 -0
  261. package/UI/esbuild-config.js +45 -0
  262. package/Utils/Analytics.ts +15 -0
  263. package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
  264. package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
  265. package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
  266. package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
  267. package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
  268. package/Utils/Dashboard/Components/Index.ts +28 -0
  269. package/Utils/DataSource/DataSourceQueryText.ts +94 -0
  270. package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
  271. package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
  272. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
  273. package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
  274. package/Utils/StatusPage/ResourceExplorer.ts +853 -0
  275. package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
  276. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
  278. package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
  279. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  280. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
  282. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/User.js +2 -0
  284. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
  286. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
  288. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
  290. package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
  292. package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
  294. package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
  295. package/build/dist/Server/API/AIInsightAPI.js +34 -4
  296. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  297. package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
  298. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  299. package/build/dist/Server/API/DashboardAPI.js +119 -433
  300. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  301. package/build/dist/Server/API/DataSourceAPI.js +173 -0
  302. package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
  303. package/build/dist/Server/API/StatusPageAPI.js +11 -1
  304. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  305. package/build/dist/Server/API/UserAPI.js +94 -2
  306. package/build/dist/Server/API/UserAPI.js.map +1 -1
  307. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
  308. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  309. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
  310. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
  311. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
  312. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
  313. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
  314. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
  315. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  316. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  317. package/build/dist/Server/Infrastructure/Queue.js +27 -0
  318. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  319. package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
  320. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  321. package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
  322. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  323. package/build/dist/Server/Services/AIInsightService.js +110 -10
  324. package/build/dist/Server/Services/AIInsightService.js.map +1 -1
  325. package/build/dist/Server/Services/AIRunService.js +34 -0
  326. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  327. package/build/dist/Server/Services/AIService.js +16 -2
  328. package/build/dist/Server/Services/AIService.js.map +1 -1
  329. package/build/dist/Server/Services/AlertService.js +28 -35
  330. package/build/dist/Server/Services/AlertService.js.map +1 -1
  331. package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
  332. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  333. package/build/dist/Server/Services/DataSourceService.js +159 -0
  334. package/build/dist/Server/Services/DataSourceService.js.map +1 -0
  335. package/build/dist/Server/Services/HostService.js +74 -0
  336. package/build/dist/Server/Services/HostService.js.map +1 -1
  337. package/build/dist/Server/Services/IncidentService.js +35 -24
  338. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  339. package/build/dist/Server/Services/Index.js +2 -0
  340. package/build/dist/Server/Services/Index.js.map +1 -1
  341. package/build/dist/Server/Services/MonitorService.js +45 -0
  342. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  343. package/build/dist/Server/Services/MonitorStatusService.js +129 -0
  344. package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
  345. package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
  346. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  347. package/build/dist/Server/Services/RumSessionPinService.js +7 -15
  348. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  349. package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
  350. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  351. package/build/dist/Server/Services/UserService.js +241 -10
  352. package/build/dist/Server/Services/UserService.js.map +1 -1
  353. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
  354. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
  356. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
  358. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
  360. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  361. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
  362. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  363. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
  364. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  365. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
  366. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
  368. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  369. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
  372. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  373. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
  374. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  375. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
  376. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
  377. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
  378. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
  379. package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
  380. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
  381. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
  382. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
  383. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
  384. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
  385. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
  386. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
  387. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
  388. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
  389. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
  390. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
  391. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
  392. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
  393. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
  394. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
  395. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
  396. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
  397. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
  398. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
  399. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
  400. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
  401. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
  402. package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
  403. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
  404. package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
  405. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
  407. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
  408. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
  409. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
  410. package/build/dist/Server/Utils/DataSource/Types.js +2 -0
  411. package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
  412. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
  413. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
  414. package/build/dist/Server/Utils/InProcessMemo.js +113 -0
  415. package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
  416. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
  417. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
  418. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
  419. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  420. package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
  421. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  422. package/build/dist/Server/Utils/Response.js +9 -1
  423. package/build/dist/Server/Utils/Response.js.map +1 -1
  424. package/build/dist/Server/Utils/SSRFProtection.js +192 -0
  425. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
  426. package/build/dist/Server/Utils/StartServer.js +7 -0
  427. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  428. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
  429. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
  430. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
  431. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  432. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
  433. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
  434. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
  435. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
  436. package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
  437. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  438. package/build/dist/Server/Utils/Telemetry.js +93 -6
  439. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  440. package/build/dist/Server/Utils/VendorAssets.js +121 -0
  441. package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
  442. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
  443. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  444. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
  445. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  446. package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
  447. package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
  448. package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
  449. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  450. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
  451. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
  452. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
  453. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
  454. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
  455. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
  456. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
  457. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
  458. package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
  459. package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
  460. package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
  461. package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
  462. package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
  463. package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
  464. package/build/dist/Types/DataSource/DataSourceType.js +183 -0
  465. package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
  466. package/build/dist/Types/Date.js +38 -3
  467. package/build/dist/Types/Date.js.map +1 -1
  468. package/build/dist/Types/Password.js +56 -0
  469. package/build/dist/Types/Password.js.map +1 -0
  470. package/build/dist/Types/Permission.js +42 -0
  471. package/build/dist/Types/Permission.js.map +1 -1
  472. package/build/dist/Types/UserAuthenticationStatus.js +2 -0
  473. package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
  474. package/build/dist/UI/Components/ErrorBoundary.js +388 -72
  475. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  476. package/build/dist/UI/Components/Icon/Icon.js +10 -4
  477. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  478. package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
  479. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  480. package/build/dist/UI/Components/Modal/Modal.js +178 -19
  481. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  482. package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
  483. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  484. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
  485. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  486. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
  487. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  488. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
  489. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
  490. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
  491. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
  492. package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
  493. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
  494. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
  495. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  496. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
  497. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  498. package/build/dist/UI/Utils/TestDataSource.js +39 -0
  499. package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
  500. package/build/dist/Utils/Analytics.js +4 -0
  501. package/build/dist/Utils/Analytics.js.map +1 -1
  502. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
  503. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
  504. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
  505. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
  506. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
  507. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
  508. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
  509. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
  510. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
  511. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
  512. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  513. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  514. package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
  515. package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
  516. package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
  517. package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
  518. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
  519. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
  520. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
  521. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
  522. package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
  523. package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
  524. package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
  525. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
  526. package/jest.config.json +1 -0
  527. package/package.json +5 -1
  528. package/tsconfig.json +12 -10
@@ -15,13 +15,21 @@ import { describe, expect, test, afterEach } from "@jest/globals";
15
15
 
16
16
  /*
17
17
  * Human actions on AI insights land here via AIInsightAPI
18
- * (verdict / resolve / triage-run). Contract under test: a Dismissed
19
- * verdict also closes the insight while Confirmed leaves the status
20
- * untouched; overwriting a verdict is allowed (latest wins this is the
21
- * G11 precision measurement, not an audit trail); resolve stamps Confirmed
22
- * only when no verdict exists yet; and the triage-run read returns the
18
+ * (verdict / resolve / reopen / triage-run). Contract under test: a
19
+ * Dismissed verdict also closes the insight while Confirmed leaves the
20
+ * status untouched unless the insight was closed AS Dismissed, which
21
+ * Confirmed contradicts, so that case reopens it; overwriting a verdict is
22
+ * allowed (latest wins this is the G11 precision measurement, not an
23
+ * audit trail); resolve stamps Confirmed only when no verdict exists yet;
24
+ * reopen undoes either terminal state and CLEARS the verdict, and is a
25
+ * no-op on an already-open insight; and the triage-run read returns the
23
26
  * empty { run: null, events: [] } shape instead of erroring, reading run +
24
27
  * events as root with the ordered, capped event query.
28
+ *
29
+ * Every human action must be reversible: hiding the actions on a closed
30
+ * insight (and having no reopen at all) made a mis-click permanent AND
31
+ * kept InsightStore's dismissal cooldown suppressing the same fingerprint
32
+ * for days, which is the regression the reopen tests below pin.
25
33
  */
26
34
 
27
35
  const insightId: ObjectID = ObjectID.generate();
@@ -44,11 +52,28 @@ describe("AIInsightService.applyHumanVerdict", () => {
44
52
  jest.restoreAllMocks();
45
53
  });
46
54
 
47
- test("Confirmed: stores verdict + at + byUserId as root and leaves status untouched", async () => {
48
- const findOneById: jest.SpyInstance = jest.spyOn(
55
+ test("missing insight reject with a clear message, nothing written", async () => {
56
+ jest.spyOn(AIInsightService, "findOneById").mockResolvedValue(null);
57
+ const updateOneById: jest.SpyInstance = jest.spyOn(
49
58
  AIInsightService,
50
- "findOneById",
59
+ "updateOneById",
51
60
  );
61
+
62
+ await expect(
63
+ AIInsightService.applyHumanVerdict({
64
+ insightId,
65
+ verdict: AIInsightHumanVerdict.Confirmed,
66
+ byUserId: userId,
67
+ }),
68
+ ).rejects.toThrow(BadDataException);
69
+
70
+ expect(updateOneById).not.toHaveBeenCalled();
71
+ });
72
+
73
+ test("Confirmed on an open insight: stores verdict + at + byUserId as root and leaves status untouched", async () => {
74
+ jest
75
+ .spyOn(AIInsightService, "findOneById")
76
+ .mockResolvedValue(fakeInsight({ status: AIInsightStatus.FixOpened }));
52
77
  const updateOneById: jest.SpyInstance = jest
53
78
  .spyOn(AIInsightService, "updateOneById")
54
79
  .mockResolvedValue(undefined as never);
@@ -56,6 +81,7 @@ describe("AIInsightService.applyHumanVerdict", () => {
56
81
  const result: {
57
82
  insightId: ObjectID;
58
83
  verdict: AIInsightHumanVerdict;
84
+ status: AIInsightStatus | null;
59
85
  } = await AIInsightService.applyHumanVerdict({
60
86
  insightId,
61
87
  verdict: AIInsightHumanVerdict.Confirmed,
@@ -64,6 +90,8 @@ describe("AIInsightService.applyHumanVerdict", () => {
64
90
 
65
91
  expect(result.insightId).toBe(insightId);
66
92
  expect(result.verdict).toBe(AIInsightHumanVerdict.Confirmed);
93
+ // Reported back unchanged — confirming did not move the lifecycle.
94
+ expect(result.status).toBe(AIInsightStatus.FixOpened);
67
95
 
68
96
  expect(updateOneById).toHaveBeenCalledWith(
69
97
  expect.objectContaining({
@@ -77,16 +105,101 @@ describe("AIInsightService.applyHumanVerdict", () => {
77
105
  }),
78
106
  );
79
107
 
80
- // Confirmed must NOT touch the lifecycle status.
108
+ // Confirmed must NOT touch the lifecycle status of an open insight.
81
109
  const updateArg: { data: Record<string, unknown> } = updateOneById.mock
82
110
  .calls[0]![0] as { data: Record<string, unknown> };
83
111
  expect(updateArg.data).not.toHaveProperty("status");
112
+ });
113
+
114
+ test("Confirmed on an insight closed as Dismissed: reopens it to ActionRequired", async () => {
115
+ /*
116
+ * "Closed as noise" and "a human says it was real" cannot both hold.
117
+ * Leaving the status alone here left the page showing Dismissed next to
118
+ * Confirmed with no way back, and left InsightStore suppressing the same
119
+ * fingerprint for the whole dismissal cooldown.
120
+ */
121
+ jest
122
+ .spyOn(AIInsightService, "findOneById")
123
+ .mockResolvedValue(fakeInsight({ status: AIInsightStatus.Dismissed }));
124
+ const updateOneById: jest.SpyInstance = jest
125
+ .spyOn(AIInsightService, "updateOneById")
126
+ .mockResolvedValue(undefined as never);
127
+
128
+ const result: {
129
+ insightId: ObjectID;
130
+ verdict: AIInsightHumanVerdict;
131
+ status: AIInsightStatus | null;
132
+ } = await AIInsightService.applyHumanVerdict({
133
+ insightId,
134
+ verdict: AIInsightHumanVerdict.Confirmed,
135
+ byUserId: userId,
136
+ });
137
+
138
+ expect(result.status).toBe(AIInsightStatus.ActionRequired);
139
+ expect(updateOneById).toHaveBeenCalledWith(
140
+ expect.objectContaining({
141
+ data: expect.objectContaining({
142
+ humanVerdict: AIInsightHumanVerdict.Confirmed,
143
+ status: AIInsightStatus.ActionRequired,
144
+ }),
145
+ }),
146
+ );
147
+ });
148
+
149
+ test("Confirmed on a dismissed insight with a fix task: reopens to FixOpened, not ActionRequired", async () => {
150
+ jest.spyOn(AIInsightService, "findOneById").mockResolvedValue(
151
+ fakeInsight({
152
+ status: AIInsightStatus.Dismissed,
153
+ fixAiRunId: ObjectID.generate(),
154
+ }),
155
+ );
156
+ const updateOneById: jest.SpyInstance = jest
157
+ .spyOn(AIInsightService, "updateOneById")
158
+ .mockResolvedValue(undefined as never);
159
+
160
+ await AIInsightService.applyHumanVerdict({
161
+ insightId,
162
+ verdict: AIInsightHumanVerdict.Confirmed,
163
+ byUserId: userId,
164
+ });
165
+
166
+ expect(updateOneById).toHaveBeenCalledWith(
167
+ expect.objectContaining({
168
+ data: expect.objectContaining({ status: AIInsightStatus.FixOpened }),
169
+ }),
170
+ );
171
+ });
84
172
 
85
- // The write is unconditional no read-before-write guard.
86
- expect(findOneById).not.toHaveBeenCalled();
173
+ test("Confirmed on a Resolved insight leaves it Resolved (only Dismissed is contradicted)", async () => {
174
+ jest
175
+ .spyOn(AIInsightService, "findOneById")
176
+ .mockResolvedValue(fakeInsight({ status: AIInsightStatus.Resolved }));
177
+ const updateOneById: jest.SpyInstance = jest
178
+ .spyOn(AIInsightService, "updateOneById")
179
+ .mockResolvedValue(undefined as never);
180
+
181
+ const result: {
182
+ insightId: ObjectID;
183
+ verdict: AIInsightHumanVerdict;
184
+ status: AIInsightStatus | null;
185
+ } = await AIInsightService.applyHumanVerdict({
186
+ insightId,
187
+ verdict: AIInsightHumanVerdict.Confirmed,
188
+ byUserId: userId,
189
+ });
190
+
191
+ expect(result.status).toBe(AIInsightStatus.Resolved);
192
+ const updateArg: { data: Record<string, unknown> } = updateOneById.mock
193
+ .calls[0]![0] as { data: Record<string, unknown> };
194
+ expect(updateArg.data).not.toHaveProperty("status");
87
195
  });
88
196
 
89
197
  test("Dismissed: additionally closes the insight (status = Dismissed)", async () => {
198
+ jest
199
+ .spyOn(AIInsightService, "findOneById")
200
+ .mockResolvedValue(
201
+ fakeInsight({ status: AIInsightStatus.ActionRequired }),
202
+ );
90
203
  const updateOneById: jest.SpyInstance = jest
91
204
  .spyOn(AIInsightService, "updateOneById")
92
205
  .mockResolvedValue(undefined as never);
@@ -112,6 +225,11 @@ describe("AIInsightService.applyHumanVerdict", () => {
112
225
  * There is deliberately no "already has a verdict" guard — people
113
226
  * change their minds, and the G11 measurement wants the latest call.
114
227
  */
228
+ jest
229
+ .spyOn(AIInsightService, "findOneById")
230
+ .mockResolvedValue(
231
+ fakeInsight({ status: AIInsightStatus.ActionRequired }),
232
+ );
115
233
  const updateOneById: jest.SpyInstance = jest
116
234
  .spyOn(AIInsightService, "updateOneById")
117
235
  .mockResolvedValue(undefined as never);
@@ -126,6 +244,7 @@ describe("AIInsightService.applyHumanVerdict", () => {
126
244
  const result: {
127
245
  insightId: ObjectID;
128
246
  verdict: AIInsightHumanVerdict;
247
+ status: AIInsightStatus | null;
129
248
  } = await AIInsightService.applyHumanVerdict({
130
249
  insightId,
131
250
  verdict: AIInsightHumanVerdict.Dismissed,
@@ -146,6 +265,117 @@ describe("AIInsightService.applyHumanVerdict", () => {
146
265
  });
147
266
  });
148
267
 
268
+ describe("AIInsightService.reopenInsight", () => {
269
+ afterEach(() => {
270
+ jest.restoreAllMocks();
271
+ });
272
+
273
+ test("missing insight → reject with a clear message, nothing written", async () => {
274
+ jest.spyOn(AIInsightService, "findOneById").mockResolvedValue(null);
275
+ const updateOneById: jest.SpyInstance = jest.spyOn(
276
+ AIInsightService,
277
+ "updateOneById",
278
+ );
279
+
280
+ await expect(AIInsightService.reopenInsight({ insightId })).rejects.toThrow(
281
+ BadDataException,
282
+ );
283
+
284
+ expect(updateOneById).not.toHaveBeenCalled();
285
+ });
286
+
287
+ test("Dismissed → ActionRequired, and the verdict fields are cleared", async () => {
288
+ /*
289
+ * Clearing is the point: a verdict the human took back must stop
290
+ * counting toward per-detector precision, and a stale humanVerdictAt
291
+ * would otherwise anchor InsightStore's dismissal cooldown.
292
+ */
293
+ jest.spyOn(AIInsightService, "findOneById").mockResolvedValue(
294
+ fakeInsight({
295
+ status: AIInsightStatus.Dismissed,
296
+ humanVerdict: AIInsightHumanVerdict.Dismissed,
297
+ }),
298
+ );
299
+ const updateOneById: jest.SpyInstance = jest
300
+ .spyOn(AIInsightService, "updateOneById")
301
+ .mockResolvedValue(undefined as never);
302
+
303
+ const result: { insightId: ObjectID; status: AIInsightStatus } =
304
+ await AIInsightService.reopenInsight({ insightId });
305
+
306
+ expect(result.status).toBe(AIInsightStatus.ActionRequired);
307
+
308
+ expect(updateOneById).toHaveBeenCalledWith(
309
+ expect.objectContaining({
310
+ id: insightId,
311
+ props: expect.objectContaining({ isRoot: true }),
312
+ }),
313
+ );
314
+
315
+ const updateArg: { data: Record<string, unknown> } = updateOneById.mock
316
+ .calls[0]![0] as { data: Record<string, unknown> };
317
+ expect(updateArg.data["status"]).toBe(AIInsightStatus.ActionRequired);
318
+ // Explicit nulls — undefined would leave the columns as they were.
319
+ expect(updateArg.data["humanVerdict"]).toBeNull();
320
+ expect(updateArg.data["humanVerdictAt"]).toBeNull();
321
+ expect(updateArg.data["humanVerdictByUserId"]).toBeNull();
322
+ });
323
+
324
+ test("Resolved → ActionRequired too: both terminal states are reversible", async () => {
325
+ jest.spyOn(AIInsightService, "findOneById").mockResolvedValue(
326
+ fakeInsight({
327
+ status: AIInsightStatus.Resolved,
328
+ humanVerdict: AIInsightHumanVerdict.Confirmed,
329
+ }),
330
+ );
331
+ const updateOneById: jest.SpyInstance = jest
332
+ .spyOn(AIInsightService, "updateOneById")
333
+ .mockResolvedValue(undefined as never);
334
+
335
+ const result: { insightId: ObjectID; status: AIInsightStatus } =
336
+ await AIInsightService.reopenInsight({ insightId });
337
+
338
+ expect(result.status).toBe(AIInsightStatus.ActionRequired);
339
+ expect(updateOneById).toHaveBeenCalledTimes(1);
340
+ });
341
+
342
+ test("a closed insight with a fix task reopens to FixOpened", async () => {
343
+ jest.spyOn(AIInsightService, "findOneById").mockResolvedValue(
344
+ fakeInsight({
345
+ status: AIInsightStatus.Resolved,
346
+ fixAiRunId: ObjectID.generate(),
347
+ }),
348
+ );
349
+ const updateOneById: jest.SpyInstance = jest
350
+ .spyOn(AIInsightService, "updateOneById")
351
+ .mockResolvedValue(undefined as never);
352
+
353
+ const result: { insightId: ObjectID; status: AIInsightStatus } =
354
+ await AIInsightService.reopenInsight({ insightId });
355
+
356
+ expect(result.status).toBe(AIInsightStatus.FixOpened);
357
+ const updateArg: { data: Record<string, unknown> } = updateOneById.mock
358
+ .calls[0]![0] as { data: Record<string, unknown> };
359
+ expect(updateArg.data["status"]).toBe(AIInsightStatus.FixOpened);
360
+ });
361
+
362
+ test("already open: no-op that reports the current status (a double click cannot rewrite it)", async () => {
363
+ jest
364
+ .spyOn(AIInsightService, "findOneById")
365
+ .mockResolvedValue(fakeInsight({ status: AIInsightStatus.FixOpened }));
366
+ const updateOneById: jest.SpyInstance = jest.spyOn(
367
+ AIInsightService,
368
+ "updateOneById",
369
+ );
370
+
371
+ const result: { insightId: ObjectID; status: AIInsightStatus } =
372
+ await AIInsightService.reopenInsight({ insightId });
373
+
374
+ expect(result.status).toBe(AIInsightStatus.FixOpened);
375
+ expect(updateOneById).not.toHaveBeenCalled();
376
+ });
377
+ });
378
+
149
379
  describe("AIInsightService.resolveInsight", () => {
150
380
  afterEach(() => {
151
381
  jest.restoreAllMocks();
@@ -219,6 +449,31 @@ describe("AIInsightService.resolveInsight", () => {
219
449
  expect(Object.keys(updateArg.data)).toEqual(["status"]);
220
450
  expect(updateArg.data["status"]).toBe(AIInsightStatus.Resolved);
221
451
  });
452
+
453
+ /*
454
+ * The store's re-file cooldown is keyed on the CURRENT terminal status, so
455
+ * flipping a Dismissed insight to Resolved would silently trade a
456
+ * dismissal's 7-day quiet for a resolve's 24-hour one — a finding a human
457
+ * called noise would come back. The dashboard hides the action on terminal
458
+ * insights; this closes the API path.
459
+ */
460
+ test.each([[AIInsightStatus.Dismissed], [AIInsightStatus.Resolved]])(
461
+ "an already-%s insight cannot be resolved again — nothing is written",
462
+ async (status: AIInsightStatus) => {
463
+ jest
464
+ .spyOn(AIInsightService, "findOneById")
465
+ .mockResolvedValue(fakeInsight({ status }));
466
+ const updateOneById: jest.SpyInstance = jest
467
+ .spyOn(AIInsightService, "updateOneById")
468
+ .mockResolvedValue(undefined as never);
469
+
470
+ await expect(
471
+ AIInsightService.resolveInsight({ insightId, byUserId: userId }),
472
+ ).rejects.toThrow(BadDataException);
473
+
474
+ expect(updateOneById).not.toHaveBeenCalled();
475
+ },
476
+ );
222
477
  });
223
478
 
224
479
  describe("AIInsightService.getLatestTriageRunWithEvents", () => {
@@ -0,0 +1,160 @@
1
+ import AIRunService from "../../../Server/Services/AIRunService";
2
+ import AIRunStatus from "../../../Types/AI/AIRunStatus";
3
+ import ObjectID from "../../../Types/ObjectID";
4
+ import { afterEach, describe, expect, test } from "@jest/globals";
5
+
6
+ /*
7
+ * setInvestigationAnalysisTldr writes display-only text, but it still must be
8
+ * scoped: only the run it summarizes, only while that run is Completed, and
9
+ * never a soft-deleted row. A stale attempt that lost the completion race (so
10
+ * never posts a report) must not be able to label the run either.
11
+ */
12
+
13
+ interface RecordedQuery {
14
+ set: Record<string, unknown> | null;
15
+ wheres: Array<{ clause: string; parameters: Record<string, unknown> }>;
16
+ }
17
+
18
+ function mockUpdateQueryBuilder(data: { affected: number | undefined }): {
19
+ recorded: RecordedQuery;
20
+ } {
21
+ const recorded: RecordedQuery = { set: null, wheres: [] };
22
+
23
+ const builder: Record<string, unknown> = {
24
+ update: () => {
25
+ return builder;
26
+ },
27
+ set: (values: Record<string, unknown>) => {
28
+ recorded.set = values;
29
+ return builder;
30
+ },
31
+ where: (clause: string, parameters: Record<string, unknown>) => {
32
+ recorded.wheres.push({ clause, parameters });
33
+ return builder;
34
+ },
35
+ andWhere: (clause: string, parameters?: Record<string, unknown>) => {
36
+ recorded.wheres.push({ clause, parameters: parameters || {} });
37
+ return builder;
38
+ },
39
+ execute: async () => {
40
+ return { affected: data.affected };
41
+ },
42
+ };
43
+
44
+ jest.spyOn(AIRunService, "getRepository").mockReturnValue({
45
+ createQueryBuilder: () => {
46
+ return builder;
47
+ },
48
+ } as never);
49
+
50
+ return { recorded };
51
+ }
52
+
53
+ function whereClauses(recorded: RecordedQuery): string {
54
+ return recorded.wheres
55
+ .map((where: { clause: string }): string => {
56
+ return where.clause;
57
+ })
58
+ .join(" AND ");
59
+ }
60
+
61
+ describe("AIRunService.setInvestigationAnalysisTldr", () => {
62
+ afterEach(() => {
63
+ jest.restoreAllMocks();
64
+ });
65
+
66
+ test("writes only the summary, scoped to that Completed, undeleted run", async () => {
67
+ const aiRunId: ObjectID = ObjectID.generate();
68
+ const { recorded } = mockUpdateQueryBuilder({ affected: 1 });
69
+
70
+ await expect(
71
+ AIRunService.setInvestigationAnalysisTldr({
72
+ aiRunId,
73
+ analysisTldr: "Checkout is failing on an exhausted pool.",
74
+ }),
75
+ ).resolves.toBe(1);
76
+
77
+ expect(recorded.set).toEqual({
78
+ analysisTldr: "Checkout is failing on an exhausted pool.",
79
+ });
80
+
81
+ const clauses: string = whereClauses(recorded);
82
+ expect(clauses).toContain('"_id" = :id');
83
+ expect(clauses).toContain('"status" = :status');
84
+ expect(clauses).toContain('"deletedAt" IS NULL');
85
+ expect(recorded.wheres[0]!.parameters).toEqual({
86
+ id: aiRunId.toString(),
87
+ });
88
+ expect(recorded.wheres[1]!.parameters).toEqual({
89
+ status: AIRunStatus.Completed,
90
+ });
91
+ });
92
+
93
+ /*
94
+ * A display-only writer must not be able to touch anything else. This is
95
+ * the only thing standing between "set one varchar" and an UPDATE that
96
+ * silently rewrites status or the code-fix decision on a settled run.
97
+ */
98
+ test("writes that column and nothing else", async () => {
99
+ const { recorded } = mockUpdateQueryBuilder({ affected: 1 });
100
+
101
+ await AIRunService.setInvestigationAnalysisTldr({
102
+ aiRunId: ObjectID.generate(),
103
+ analysisTldr: "Summary of the outage.",
104
+ });
105
+
106
+ expect(Object.keys(recorded.set || {})).toEqual(["analysisTldr"]);
107
+ });
108
+
109
+ /*
110
+ * Write-once. A stale attempt that lost the Completed CAS is kept out today
111
+ * only by statement order in the engine — and by the time it could run, the
112
+ * WINNER has already written both the report and its summary, so a
113
+ * status-only guard would let the loser overwrite a summary describing a
114
+ * different analysis.
115
+ */
116
+ test("refuses to overwrite a summary that already exists", async () => {
117
+ const aiRunId: ObjectID = ObjectID.generate();
118
+ const { recorded } = mockUpdateQueryBuilder({ affected: 1 });
119
+
120
+ await AIRunService.setInvestigationAnalysisTldr({
121
+ aiRunId,
122
+ analysisTldr: "Summary of the outage.",
123
+ });
124
+
125
+ expect(whereClauses(recorded)).toContain('"analysisTldr" IS NULL');
126
+ });
127
+
128
+ test("reports zero when another writer already summarized the run", async () => {
129
+ mockUpdateQueryBuilder({ affected: 0 });
130
+
131
+ await expect(
132
+ AIRunService.setInvestigationAnalysisTldr({
133
+ aiRunId: ObjectID.generate(),
134
+ analysisTldr: "A second, conflicting summary.",
135
+ }),
136
+ ).resolves.toBe(0);
137
+ });
138
+
139
+ test("reports zero when the run is no longer Completed", async () => {
140
+ mockUpdateQueryBuilder({ affected: 0 });
141
+
142
+ await expect(
143
+ AIRunService.setInvestigationAnalysisTldr({
144
+ aiRunId: ObjectID.generate(),
145
+ analysisTldr: "Summary.",
146
+ }),
147
+ ).resolves.toBe(0);
148
+ });
149
+
150
+ test("treats an undefined affected count as no rows changed", async () => {
151
+ mockUpdateQueryBuilder({ affected: undefined });
152
+
153
+ await expect(
154
+ AIRunService.setInvestigationAnalysisTldr({
155
+ aiRunId: ObjectID.generate(),
156
+ analysisTldr: "Summary.",
157
+ }),
158
+ ).resolves.toBe(0);
159
+ });
160
+ });
@@ -8,6 +8,7 @@ import AIService, {
8
8
  AI_INCIDENT_INVESTIGATION_FEATURE,
9
9
  AI_INSIGHT_TRIAGE_FEATURE,
10
10
  AI_INVESTIGATION_GRADING_FEATURE,
11
+ AI_INVESTIGATION_TLDR_FEATURE,
11
12
  AI_REMEDIATION_EXECUTION_FEATURE,
12
13
  AI_REMEDIATION_PLANNING_FEATURE,
13
14
  RUNBOOK_AI_STEP_FEATURE,
@@ -77,6 +78,7 @@ describe("AUTONOMOUS_AI_FEATURES persisted labels", () => {
77
78
  expect(AI_CONFIDENCE_CLASSIFICATION_FEATURE).toBe(
78
79
  "AI Confidence Classification",
79
80
  );
81
+ expect(AI_INVESTIGATION_TLDR_FEATURE).toBe("AI Investigation TLDR");
80
82
  expect(AI_CODE_FIX_FEATURE).toBe("AI Code Fix");
81
83
  expect(AI_INSIGHT_TRIAGE_FEATURE).toBe("AI Insight Triage");
82
84
  expect(AI_REMEDIATION_PLANNING_FEATURE).toBe("AI Remediation Planning");
@@ -91,6 +93,7 @@ describe("AUTONOMOUS_AI_FEATURES persisted labels", () => {
91
93
  AI_ALERT_INVESTIGATION_FEATURE,
92
94
  AI_INVESTIGATION_GRADING_FEATURE,
93
95
  AI_CONFIDENCE_CLASSIFICATION_FEATURE,
96
+ AI_INVESTIGATION_TLDR_FEATURE,
94
97
  AI_CODE_FIX_FEATURE,
95
98
  AI_INSIGHT_TRIAGE_FEATURE,
96
99
  AI_REMEDIATION_PLANNING_FEATURE,
@@ -136,6 +139,7 @@ describe("AUTONOMOUS_AI_FEATURES persisted labels", () => {
136
139
  AI_ALERT_INVESTIGATION_FEATURE,
137
140
  AI_INVESTIGATION_GRADING_FEATURE,
138
141
  AI_CONFIDENCE_CLASSIFICATION_FEATURE,
142
+ AI_INVESTIGATION_TLDR_FEATURE,
139
143
  AI_CODE_FIX_FEATURE,
140
144
  AI_INSIGHT_TRIAGE_FEATURE,
141
145
  AI_REMEDIATION_PLANNING_FEATURE,