@oneuptime/common 12.0.4 → 12.0.5

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 (374) hide show
  1. package/Models/DatabaseModels/AIRun.ts +38 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +30 -0
  3. package/Models/DatabaseModels/Dashboard.ts +28 -0
  4. package/Models/DatabaseModels/Incident.ts +2 -0
  5. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  7. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  8. package/Models/DatabaseModels/IncidentFeed.ts +30 -0
  9. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  10. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  11. package/Models/DatabaseModels/LogSavedView.ts +33 -0
  12. package/Models/DatabaseModels/Project.ts +231 -9
  13. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  14. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  15. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  16. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
  17. package/Models/DatabaseModels/StatusPage.ts +28 -0
  18. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  19. package/Server/API/AIAgentDataAPI.ts +44 -55
  20. package/Server/API/AIInvestigationAPI.ts +175 -17
  21. package/Server/API/DashboardAPI.ts +10 -10
  22. package/Server/API/StatusPageAPI.ts +38 -19
  23. package/Server/EnvironmentConfig.ts +16 -0
  24. package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
  25. package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  32. package/Server/Services/AIRunService.ts +78 -10
  33. package/Server/Services/AIService.ts +94 -22
  34. package/Server/Services/AlertFeedService.ts +5 -0
  35. package/Server/Services/AnalyticsDatabaseService.ts +29 -0
  36. package/Server/Services/DatabaseService.ts +43 -2
  37. package/Server/Services/IncidentFeedService.ts +5 -0
  38. package/Server/Services/LlmLogService.ts +46 -2
  39. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
  40. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
  41. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
  42. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
  43. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
  44. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
  45. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
  46. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
  47. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
  48. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
  49. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
  50. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
  51. package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
  52. package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
  53. package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
  54. package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
  55. package/Server/Utils/AI/SRE/README.md +1 -1
  56. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
  57. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
  58. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
  59. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
  60. package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
  61. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  62. package/Server/Utils/PasswordHash.ts +28 -4
  63. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
  64. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
  65. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
  66. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
  67. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
  68. package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
  69. package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
  70. package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
  71. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
  72. package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
  73. package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
  74. package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
  75. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
  76. package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
  77. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
  78. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
  79. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
  80. package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
  81. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +25 -1
  82. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +45 -35
  83. package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
  84. package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
  85. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
  86. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
  87. package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
  88. package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
  89. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
  90. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
  91. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
  92. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
  93. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
  94. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
  95. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
  96. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
  97. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
  98. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
  99. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
  100. package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
  101. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
  102. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
  103. package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
  104. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
  105. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
  106. package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
  107. package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
  108. package/Tests/Server/Utils/PasswordHash.test.ts +30 -0
  109. package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
  110. package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
  111. package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
  112. package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
  113. package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
  114. package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
  115. package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
  116. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
  117. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
  118. package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
  119. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
  120. package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
  121. package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
  122. package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
  123. package/Tests/Types/Permission.test.ts +137 -0
  124. package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
  125. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
  126. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
  127. package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
  128. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
  129. package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
  130. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
  131. package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
  132. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
  133. package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
  134. package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
  135. package/Tests/UI/Utils/Project.test.ts +31 -0
  136. package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
  137. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
  138. package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
  139. package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
  140. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
  141. package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
  142. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
  143. package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
  144. package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
  145. package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
  146. package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
  147. package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
  148. package/Types/AI/CodeFixTaskContext.ts +63 -3
  149. package/Types/AI/CodeFixTaskType.ts +3 -3
  150. package/Types/HashedString.ts +4 -3
  151. package/Types/Monitor/CriteriaFilter.ts +4 -0
  152. package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
  153. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
  155. package/Types/Monitor/MonitorMetricType.ts +8 -0
  156. package/Types/Monitor/MonitorStep.ts +10 -1
  157. package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
  158. package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
  159. package/Types/Permission.ts +23 -175
  160. package/Types/Probe/ProbeMonitorResponse.ts +6 -0
  161. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
  162. package/UI/Components/ErrorBoundary.tsx +138 -11
  163. package/UI/Components/Feed/FeedItem.tsx +9 -2
  164. package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
  165. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  166. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
  167. package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
  168. package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
  169. package/UI/Utils/DownloadFile.ts +16 -8
  170. package/UI/Utils/ErrorSupportBundle.ts +805 -0
  171. package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
  172. package/UI/Utils/Project.ts +4 -0
  173. package/UI/Utils/StatusPage.ts +8 -2
  174. package/UI/Utils/UseDashboardGridDnd.ts +917 -0
  175. package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
  176. package/Utils/Dashboard/GridLayout.ts +523 -0
  177. package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
  178. package/Utils/Monitor/MonitorMetricType.ts +44 -2
  179. package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
  180. package/Utils/StatusPage/GroupTree.ts +157 -66
  181. package/Utils/StatusPage/ResourceUptime.ts +37 -2
  182. package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
  183. package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
  184. package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
  185. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
  187. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
  189. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  191. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  193. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  195. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  197. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
  199. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  201. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  203. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
  205. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/Project.js +241 -11
  207. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  209. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  211. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  212. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  213. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  214. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
  215. package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
  216. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  218. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  219. package/build/dist/Server/API/AIAgentDataAPI.js +28 -46
  220. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  221. package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
  222. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  223. package/build/dist/Server/API/DashboardAPI.js +8 -5
  224. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  225. package/build/dist/Server/API/StatusPageAPI.js +29 -11
  226. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  227. package/build/dist/Server/EnvironmentConfig.js +14 -0
  228. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  229. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
  230. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  231. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
  232. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  245. package/build/dist/Server/Services/AIRunService.js +58 -12
  246. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  247. package/build/dist/Server/Services/AIService.js +74 -21
  248. package/build/dist/Server/Services/AIService.js.map +1 -1
  249. package/build/dist/Server/Services/AlertFeedService.js +3 -0
  250. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  251. package/build/dist/Server/Services/AnalyticsDatabaseService.js +29 -1
  252. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  253. package/build/dist/Server/Services/DatabaseService.js +21 -2
  254. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  255. package/build/dist/Server/Services/IncidentFeedService.js +3 -0
  256. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  257. package/build/dist/Server/Services/LlmLogService.js +22 -1
  258. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  259. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  260. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  261. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
  262. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
  263. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
  264. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  265. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
  266. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  267. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
  268. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  269. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
  270. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  271. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
  272. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  273. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
  274. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  275. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
  276. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
  277. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
  278. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  279. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
  280. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  281. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
  282. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  283. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
  284. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
  285. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
  286. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  287. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
  288. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
  289. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
  290. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
  291. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
  292. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
  293. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
  294. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  295. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
  296. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  297. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
  298. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  299. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  300. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  301. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  302. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  303. package/build/dist/Server/Utils/PasswordHash.js +25 -4
  304. package/build/dist/Server/Utils/PasswordHash.js.map +1 -1
  305. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
  306. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
  307. package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
  308. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  309. package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
  310. package/build/dist/Types/HashedString.js +4 -3
  311. package/build/dist/Types/HashedString.js.map +1 -1
  312. package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
  313. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  314. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
  315. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
  316. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
  317. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  318. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  319. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  320. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  321. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  322. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
  323. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  324. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
  325. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
  326. package/build/dist/Types/Permission.js +23 -155
  327. package/build/dist/Types/Permission.js.map +1 -1
  328. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
  329. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  330. package/build/dist/UI/Components/ErrorBoundary.js +67 -8
  331. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  332. package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
  333. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  334. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
  335. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  336. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  338. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
  339. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  340. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
  343. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  344. package/build/dist/UI/Utils/DownloadFile.js +15 -8
  345. package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
  346. package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
  347. package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
  348. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
  349. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  350. package/build/dist/UI/Utils/Project.js +3 -0
  351. package/build/dist/UI/Utils/Project.js.map +1 -1
  352. package/build/dist/UI/Utils/StatusPage.js +4 -4
  353. package/build/dist/UI/Utils/StatusPage.js.map +1 -1
  354. package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
  355. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
  356. package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
  357. package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
  358. package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
  359. package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
  360. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
  361. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
  362. package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
  363. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  364. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
  365. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
  366. package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
  367. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
  368. package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
  369. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  370. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
  371. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
  372. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
  373. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
  374. package/package.json +1 -1
@@ -53,7 +53,6 @@ import JSONFunctions from "../../Types/JSONFunctions";
53
53
  import ObjectID from "../../Types/ObjectID";
54
54
  import Phone from "../../Types/Phone";
55
55
  import PositiveNumber from "../../Types/PositiveNumber";
56
- import HashedString from "../../Types/HashedString";
57
56
  import AcmeChallenge from "../../Models/DatabaseModels/AcmeChallenge";
58
57
  import Incident from "../../Models/DatabaseModels/Incident";
59
58
  import IncidentEpisode from "../../Models/DatabaseModels/IncidentEpisode";
@@ -85,7 +84,9 @@ import StatusPageOIDC from "../../Models/DatabaseModels/StatusPageOidc";
85
84
  import StatusPageSubscriber from "../../Models/DatabaseModels/StatusPageSubscriber";
86
85
  import StatusPageEventType from "../../Types/StatusPage/StatusPageEventType";
87
86
  import StatusPageResourceUptimeUtil from "../../Utils/StatusPage/ResourceUptime";
88
- import StatusPageGroupTreeUtil from "../../Utils/StatusPage/GroupTree";
87
+ import StatusPageGroupTreeUtil, {
88
+ StatusPageGroupTreeIndex,
89
+ } from "../../Utils/StatusPage/GroupTree";
89
90
  import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
90
91
  import { Green } from "../../Types/BrandColors";
91
92
  import UptimeUtil, { UptimeWindow } from "../../Utils/Uptime/UptimeUtil";
@@ -100,7 +101,6 @@ import Hostname from "../../Types/API/Hostname";
100
101
  import Protocol from "../../Types/API/Protocol";
101
102
  import DatabaseConfig from "../DatabaseConfig";
102
103
  import CookieUtil from "../Utils/Cookie";
103
- import { EncryptionSecret } from "../EnvironmentConfig";
104
104
  import { StatusPageApiRoute } from "../../ServiceRoute";
105
105
  import ProjectSmtpConfigService from "../Services/ProjectSmtpConfigService";
106
106
  import ForbiddenException from "../../Types/Exception/ForbiddenException";
@@ -941,10 +941,9 @@ export default class StatusPageAPI extends BaseAPI<
941
941
  req.params["statusPageId"] as string,
942
942
  );
943
943
 
944
- const password: string | undefined =
945
- req.body && (req.body["password"] as string);
944
+ const password: unknown = req.body && req.body["password"];
946
945
 
947
- if (!password) {
946
+ if (typeof password !== "string" || !password) {
948
947
  throw new BadDataException("Master password is required.");
949
948
  }
950
949
 
@@ -956,6 +955,7 @@ export default class StatusPageAPI extends BaseAPI<
956
955
  projectId: true,
957
956
  enableMasterPassword: true,
958
957
  masterPassword: true,
958
+ masterPasswordSalt: true,
959
959
  isPublicStatusPage: true,
960
960
  },
961
961
  props: {
@@ -979,12 +979,14 @@ export default class StatusPageAPI extends BaseAPI<
979
979
  );
980
980
  }
981
981
 
982
- const hashedInput: string = await HashedString.hashValue(
983
- password,
984
- EncryptionSecret,
985
- );
982
+ const isMasterPasswordValid: boolean =
983
+ await StatusPageService.verifyHashedColumnValue({
984
+ item: statusPage,
985
+ columnName: "masterPassword",
986
+ plainValue: password,
987
+ });
986
988
 
987
- if (hashedInput !== statusPage.masterPassword.toString()) {
989
+ if (!isMasterPasswordValid) {
988
990
  throw new BadDataException(MASTER_PASSWORD_INVALID_MESSAGE);
989
991
  }
990
992
 
@@ -1407,19 +1409,35 @@ export default class StatusPageAPI extends BaseAPI<
1407
1409
  const resourceUptimesByGroupId: Dictionary<Array<ResourceUptime>> =
1408
1410
  {};
1409
1411
 
1412
+ /*
1413
+ * Keyed the same way, so the loop below can look a group's uptime up
1414
+ * instead of scanning the whole list for it. A status page can carry
1415
+ * well over a thousand groups, and a scan per group is a scan of the
1416
+ * whole list per group.
1417
+ */
1418
+ const groupUptimeByGroupId: Dictionary<StatusPageGroupUptime> = {};
1419
+
1410
1420
  for (const groupUptime of groupUptimes) {
1411
- resourceUptimesByGroupId[
1412
- groupUptime.statusPageGroupId?.toString() || ""
1413
- ] = groupUptime.statusPageResourceUptimes;
1421
+ const groupId: string =
1422
+ groupUptime.statusPageGroupId?.toString() || "";
1423
+
1424
+ resourceUptimesByGroupId[groupId] =
1425
+ groupUptime.statusPageResourceUptimes;
1426
+ groupUptimeByGroupId[groupId] = groupUptime;
1414
1427
  }
1415
1428
 
1429
+ /*
1430
+ * One index for every subtree walk below, rather than one
1431
+ * re-bucketing of the group list per group.
1432
+ */
1433
+ const statusPageGroupTreeIndex: StatusPageGroupTreeIndex =
1434
+ StatusPageGroupTreeUtil.buildIndex({
1435
+ statusPageGroups: statusPageGroups,
1436
+ });
1437
+
1416
1438
  for (const group of statusPageGroups) {
1417
1439
  const groupUptime: StatusPageGroupUptime | undefined =
1418
- groupUptimes.find((item: StatusPageGroupUptime) => {
1419
- return (
1420
- item.statusPageGroupId?.toString() === group.id?.toString()
1421
- );
1422
- });
1440
+ groupUptimeByGroupId[group.id?.toString() || ""];
1423
1441
 
1424
1442
  if (!groupUptime) {
1425
1443
  continue;
@@ -1429,6 +1447,7 @@ export default class StatusPageAPI extends BaseAPI<
1429
1447
  StatusPageGroupTreeUtil.getGroupAndDescendants({
1430
1448
  statusPageGroup: group,
1431
1449
  statusPageGroups: statusPageGroups,
1450
+ index: statusPageGroupTreeIndex,
1432
1451
  }).flatMap((groupInSubtree: StatusPageGroup) => {
1433
1452
  return (
1434
1453
  resourceUptimesByGroupId[
@@ -8,6 +8,7 @@ import {
8
8
  HomeRoute,
9
9
  } from "../ServiceRoute";
10
10
  import BillingConfig from "./BillingConfig";
11
+ import { getDistributedDdlTaskTimeoutSeconds } from "./Utils/AnalyticsDatabase/ClusterConfig";
11
12
  import Protocol from "../Types/API/Protocol";
12
13
  import URL from "../Types/API/URL";
13
14
  import Route from "../Types/API/Route";
@@ -569,6 +570,21 @@ export const ClickhouseClusterName: string =
569
570
  export const ClickhouseShardingKeyOverride: string =
570
571
  process.env["CLICKHOUSE_SHARDING_KEY"] || "";
571
572
 
573
+ /*
574
+ * How long migration / schema-sync ON CLUSTER DDL waits for every host to
575
+ * report completion before giving up on confirmation (the statement itself
576
+ * stays queued and still executes on every host in the background). Default
577
+ * 180 — the ClickHouse server default. Raise this on clusters whose DDL queue
578
+ * drains slowly; the migration pool's socket-idle ceiling scales with it (see
579
+ * ClickhouseConfig.ts). 0 returns immediately (async); a negative value
580
+ * removes the server-side wait limit but the client still gives up at the
581
+ * migration pool's socket-idle ceiling (30-minute floor), so prefer a finite
582
+ * value. Mirrors the live reader getDistributedDdlTaskTimeoutSeconds() in
583
+ * ClusterConfig.ts, which is the single source of parsing truth.
584
+ */
585
+ export const ClickhouseDistributedDdlTaskTimeoutSeconds: number =
586
+ getDistributedDdlTaskTimeoutSeconds();
587
+
572
588
  export const GitSha: string = process.env["GIT_SHA"] || "unknown";
573
589
 
574
590
  export const AppVersion: string = process.env["APP_VERSION"] || "unknown";
@@ -13,6 +13,7 @@ import {
13
13
  MaxClickhouseIngestConnections,
14
14
  ShouldClickhouseSslEnable,
15
15
  } from "../EnvironmentConfig";
16
+ import { getDistributedDdlTaskTimeoutSeconds } from "../Utils/AnalyticsDatabase/ClusterConfig";
16
17
  import Hostname from "../../Types/API/Hostname";
17
18
 
18
19
  export type ClickHouseClientConfigOptions = NodeClickHouseClientConfigOptions;
@@ -114,10 +115,23 @@ export const ingestDataSourceOptions: ClickHouseClientConfigOptions = {
114
115
  * additionally carry send_progress_in_http_headers (see MigrationExecuteOptions
115
116
  * in AnalyticsDatabaseService) so the socket stays non-idle, and a server-side
116
117
  * SETTINGS max_execution_time so ClickHouse remains the authoritative cap.
118
+ *
119
+ * The ON CLUSTER confirmation wait (distributed_ddl_task_timeout) streams zero
120
+ * bytes while pending, so this idle ceiling is the effective upper bound on any
121
+ * DDL confirmation wait. When CLICKHOUSE_DISTRIBUTED_DDL_TASK_TIMEOUT_SECONDS
122
+ * is raised past the 30-minute floor, scale the ceiling with it (plus slack)
123
+ * so the longer wait isn't killed client-side. A negative (infinite) DDL
124
+ * timeout is still bounded by the 30-minute floor — the client must not hang
125
+ * forever on a dead socket.
117
126
  */
127
+ const migrationRequestTimeoutInMs: number = Math.max(
128
+ 30 * 60 * 1000, // 30-minute floor
129
+ (getDistributedDdlTaskTimeoutSeconds() + 120) * 1000,
130
+ );
131
+
118
132
  export const migrationDataSourceOptions: ClickHouseClientConfigOptions = {
119
133
  ...options,
120
- request_timeout: 30 * 60 * 1000, // 30 minutes
134
+ request_timeout: migrationRequestTimeoutInMs,
121
135
  };
122
136
 
123
137
  export const testDataSourceOptions: ClickHouseClientConfigOptions =
@@ -87,7 +87,7 @@ export default class ClickhouseDatabase {
87
87
  }
88
88
 
89
89
  logger.debug(
90
- `Clickhouse Database Connected: ${dataSourceOptions.host?.toString()}`,
90
+ `Clickhouse Database Connected: ${dataSourceOptions.url?.toString()}`,
91
91
  );
92
92
 
93
93
  return clickhouseClient;
@@ -0,0 +1,27 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ /*
4
+ * A saved log view used to carry its time selection only inside the serialized
5
+ * `query`, where it had already been resolved to an absolute InBetween window.
6
+ * That froze "Past 1 Hour" into the hour it happened to be when the view was
7
+ * saved. The selection itself now lives here — the rolling range token, or the
8
+ * absolute window when the range is Custom — and is re-resolved on every apply.
9
+ *
10
+ * Nullable on purpose: rows created before this column still carry their
11
+ * absolute window in `query`, and readers fall back to it as a Custom range.
12
+ */
13
+ export class AddTimeRangeToLogSavedView1786096660558
14
+ implements MigrationInterface
15
+ {
16
+ public name = "AddTimeRangeToLogSavedView1786096660558";
17
+
18
+ public async up(queryRunner: QueryRunner): Promise<void> {
19
+ await queryRunner.query(`ALTER TABLE "LogSavedView" ADD "timeRange" jsonb`);
20
+ }
21
+
22
+ public async down(queryRunner: QueryRunner): Promise<void> {
23
+ await queryRunner.query(
24
+ `ALTER TABLE "LogSavedView" DROP COLUMN "timeRange"`,
25
+ );
26
+ }
27
+ }
@@ -0,0 +1,89 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1786101798351 implements MigrationInterface {
4
+ public name = "MigrationName1786101798351";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "Project" ADD "enableIncidentInstrumentationFixTasks" boolean NOT NULL DEFAULT false`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "Project" ADD "enableAlertInstrumentationFixTasks" boolean NOT NULL DEFAULT false`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "Project" ADD "enableAutomaticIncidentCodeFixes" boolean NOT NULL DEFAULT false`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "Project" ADD "enableAutomaticAlertCodeFixes" boolean NOT NULL DEFAULT false`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "Project" ADD "incidentAiDailyAutonomousTokenLimit" integer`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "Project" ADD "alertAiDailyAutonomousTokenLimit" integer`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "Project" ADD "incidentAiDailyFixTaskLimit" integer`,
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "Project" ADD "alertAiDailyFixTaskLimit" integer`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "Project" ADD "incidentAiMaxConcurrentInvestigations" integer`,
33
+ );
34
+ await queryRunner.query(
35
+ `ALTER TABLE "Project" ADD "alertAiMaxConcurrentInvestigations" integer`,
36
+ );
37
+ await queryRunner.query(
38
+ `UPDATE "Project" SET "enableIncidentInstrumentationFixTasks" = "enableInstrumentationFixTasks", "enableAlertInstrumentationFixTasks" = "enableInstrumentationFixTasks", "enableAutomaticIncidentCodeFixes" = "enableAutomaticCodeFixes", "enableAutomaticAlertCodeFixes" = "enableAutomaticCodeFixes", "incidentAiDailyAutonomousTokenLimit" = "aiDailyAutonomousTokenLimit", "alertAiDailyAutonomousTokenLimit" = "aiDailyAutonomousTokenLimit", "incidentAiDailyFixTaskLimit" = "aiDailyFixTaskLimit", "alertAiDailyFixTaskLimit" = "aiDailyFixTaskLimit", "incidentAiMaxConcurrentInvestigations" = "aiMaxConcurrentInvestigations", "alertAiMaxConcurrentInvestigations" = "aiMaxConcurrentInvestigations"`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "Project" DROP COLUMN "enableInstrumentationFixTasks"`,
42
+ );
43
+ await queryRunner.query(
44
+ `ALTER TABLE "Project" DROP COLUMN "enableAutomaticCodeFixes"`,
45
+ );
46
+ }
47
+
48
+ public async down(queryRunner: QueryRunner): Promise<void> {
49
+ await queryRunner.query(
50
+ `ALTER TABLE "Project" ADD "enableAutomaticCodeFixes" boolean NOT NULL DEFAULT false`,
51
+ );
52
+ await queryRunner.query(
53
+ `ALTER TABLE "Project" ADD "enableInstrumentationFixTasks" boolean NOT NULL DEFAULT false`,
54
+ );
55
+ await queryRunner.query(
56
+ `UPDATE "Project" SET "enableInstrumentationFixTasks" = "enableIncidentInstrumentationFixTasks" OR "enableAlertInstrumentationFixTasks", "enableAutomaticCodeFixes" = "enableAutomaticIncidentCodeFixes" OR "enableAutomaticAlertCodeFixes"`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "Project" DROP COLUMN "alertAiMaxConcurrentInvestigations"`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "Project" DROP COLUMN "incidentAiMaxConcurrentInvestigations"`,
63
+ );
64
+ await queryRunner.query(
65
+ `ALTER TABLE "Project" DROP COLUMN "alertAiDailyFixTaskLimit"`,
66
+ );
67
+ await queryRunner.query(
68
+ `ALTER TABLE "Project" DROP COLUMN "incidentAiDailyFixTaskLimit"`,
69
+ );
70
+ await queryRunner.query(
71
+ `ALTER TABLE "Project" DROP COLUMN "alertAiDailyAutonomousTokenLimit"`,
72
+ );
73
+ await queryRunner.query(
74
+ `ALTER TABLE "Project" DROP COLUMN "incidentAiDailyAutonomousTokenLimit"`,
75
+ );
76
+ await queryRunner.query(
77
+ `ALTER TABLE "Project" DROP COLUMN "enableAutomaticAlertCodeFixes"`,
78
+ );
79
+ await queryRunner.query(
80
+ `ALTER TABLE "Project" DROP COLUMN "enableAutomaticIncidentCodeFixes"`,
81
+ );
82
+ await queryRunner.query(
83
+ `ALTER TABLE "Project" DROP COLUMN "enableAlertInstrumentationFixTasks"`,
84
+ );
85
+ await queryRunner.query(
86
+ `ALTER TABLE "Project" DROP COLUMN "enableIncidentInstrumentationFixTasks"`,
87
+ );
88
+ }
89
+ }
@@ -0,0 +1,27 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1786105470826 implements MigrationInterface {
4
+ public name = "MigrationName1786105470826";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`ALTER TABLE "IncidentFeed" ADD "aiRunId" uuid`);
8
+ await queryRunner.query(`ALTER TABLE "AlertFeed" ADD "aiRunId" uuid`);
9
+ await queryRunner.query(
10
+ `CREATE INDEX "IDX_bae064a2cf9282fc2cca934d78" ON "IncidentFeed" ("incidentId", "aiRunId") `,
11
+ );
12
+ await queryRunner.query(
13
+ `CREATE INDEX "IDX_7da528b06c0ae8b2f1b6c9c848" ON "AlertFeed" ("alertId", "aiRunId") `,
14
+ );
15
+ }
16
+
17
+ public async down(queryRunner: QueryRunner): Promise<void> {
18
+ await queryRunner.query(
19
+ `DROP INDEX "public"."IDX_7da528b06c0ae8b2f1b6c9c848"`,
20
+ );
21
+ await queryRunner.query(
22
+ `DROP INDEX "public"."IDX_bae064a2cf9282fc2cca934d78"`,
23
+ );
24
+ await queryRunner.query(`ALTER TABLE "AlertFeed" DROP COLUMN "aiRunId"`);
25
+ await queryRunner.query(`ALTER TABLE "IncidentFeed" DROP COLUMN "aiRunId"`);
26
+ }
27
+ }
@@ -0,0 +1,40 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ type ScryptHashExistsResult = {
4
+ exists: boolean;
5
+ };
6
+
7
+ export class AddMasterPasswordSalt1786400000000 implements MigrationInterface {
8
+ public name = "AddMasterPasswordSalt1786400000000";
9
+
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ await queryRunner.query(
12
+ `ALTER TABLE "StatusPage" ADD "masterPasswordSalt" character varying(100)`,
13
+ );
14
+ await queryRunner.query(
15
+ `ALTER TABLE "Dashboard" ADD "masterPasswordSalt" character varying(100)`,
16
+ );
17
+ }
18
+
19
+ public async down(queryRunner: QueryRunner): Promise<void> {
20
+ const [dashboardResult] = (await queryRunner.query(
21
+ `SELECT EXISTS (SELECT 1 FROM "Dashboard" WHERE "masterPassword" LIKE 'scrypt$%') AS "exists"`,
22
+ )) as Array<ScryptHashExistsResult>;
23
+ const [statusPageResult] = (await queryRunner.query(
24
+ `SELECT EXISTS (SELECT 1 FROM "StatusPage" WHERE "masterPassword" LIKE 'scrypt$%') AS "exists"`,
25
+ )) as Array<ScryptHashExistsResult>;
26
+
27
+ if (dashboardResult?.exists || statusPageResult?.exists) {
28
+ throw new Error(
29
+ "Cannot remove master-password salt columns while scrypt master-password hashes exist.",
30
+ );
31
+ }
32
+
33
+ await queryRunner.query(
34
+ `ALTER TABLE "Dashboard" DROP COLUMN "masterPasswordSalt"`,
35
+ );
36
+ await queryRunner.query(
37
+ `ALTER TABLE "StatusPage" DROP COLUMN "masterPasswordSalt"`,
38
+ );
39
+ }
40
+ }
@@ -0,0 +1,26 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ /*
4
+ * Generated with `npm run generate-postgres-migration` after adding
5
+ * AIRun.codeFixRecommendation. Existing rows fail closed as NotRecommended;
6
+ * incident/alert investigations move to Pending only in their atomic
7
+ * Completed transition, then settle through structured post-analysis
8
+ * classification.
9
+ */
10
+ export class AddInvestigationCodeFixRecommendation1786500000000
11
+ implements MigrationInterface
12
+ {
13
+ public name = "AddInvestigationCodeFixRecommendation1786500000000";
14
+
15
+ public async up(queryRunner: QueryRunner): Promise<void> {
16
+ await queryRunner.query(
17
+ `ALTER TABLE "AIRun" ADD "codeFixRecommendation" character varying(100) NOT NULL DEFAULT 'NotRecommended'`,
18
+ );
19
+ }
20
+
21
+ public async down(queryRunner: QueryRunner): Promise<void> {
22
+ await queryRunner.query(
23
+ `ALTER TABLE "AIRun" DROP COLUMN "codeFixRecommendation"`,
24
+ );
25
+ }
26
+ }
@@ -501,9 +501,14 @@ import { AddRemediationVerification1785768089408 } from "./1785768089408-AddReme
501
501
  import { AddStatusPageMonitorRule1786005052769 } from "./1786005052769-AddStatusPageMonitorRule";
502
502
  import { AddPerUserPasswordSalt1786018109307 } from "./1786018109307-AddPerUserPasswordSalt";
503
503
  import { WidenHashedStringColumnsForScrypt1786023262402 } from "./1786023262402-WidenHashedStringColumnsForScrypt";
504
+ import { AddTimeRangeToLogSavedView1786096660558 } from "./1786096660558-AddTimeRangeToLogSavedView";
504
505
  import { RestoreServiceLowerNameIndex1786100000000 } from "./1786100000000-RestoreServiceLowerNameIndex";
506
+ import { MigrationName1786101798351 } from "./1786101798351-MigrationName";
507
+ import { MigrationName1786105470826 } from "./1786105470826-MigrationName";
505
508
  import { RestoreDroppedUniqueIndexes1786200000000 } from "./1786200000000-RestoreDroppedUniqueIndexes";
506
509
  import { QuarantineUnboundGitHubInstallations1786300000000 } from "./1786300000000-QuarantineUnboundGitHubInstallations";
510
+ import { AddMasterPasswordSalt1786400000000 } from "./1786400000000-AddMasterPasswordSalt";
511
+ import { AddInvestigationCodeFixRecommendation1786500000000 } from "./1786500000000-AddInvestigationCodeFixRecommendation";
507
512
 
508
513
  export default [
509
514
  InitialMigration,
@@ -1009,7 +1014,12 @@ export default [
1009
1014
  AddStatusPageMonitorRule1786005052769,
1010
1015
  AddPerUserPasswordSalt1786018109307,
1011
1016
  WidenHashedStringColumnsForScrypt1786023262402,
1017
+ AddTimeRangeToLogSavedView1786096660558,
1012
1018
  RestoreServiceLowerNameIndex1786100000000,
1013
1019
  RestoreDroppedUniqueIndexes1786200000000,
1014
1020
  QuarantineUnboundGitHubInstallations1786300000000,
1021
+ MigrationName1786101798351,
1022
+ AddMasterPasswordSalt1786400000000,
1023
+ MigrationName1786105470826,
1024
+ AddInvestigationCodeFixRecommendation1786500000000,
1015
1025
  ];
@@ -3,12 +3,17 @@ import ObjectID from "../../Types/ObjectID";
3
3
  import OneUptimeDate from "../../Types/Date";
4
4
  import AIRunStatus from "../../Types/AI/AIRunStatus";
5
5
  import AIRunType from "../../Types/AI/AIRunType";
6
+ import AIRunCodeFixRecommendation from "../../Types/AI/AIRunCodeFixRecommendation";
6
7
  import AIRunHumanVerdict from "../../Types/AI/AIRunHumanVerdict";
7
8
  import BadDataException from "../../Types/Exception/BadDataException";
8
9
  import CodeFixTaskType, {
9
10
  CodeFixContextKind,
10
11
  CodeFixTaskTypeHelper,
11
12
  } from "../../Types/AI/CodeFixTaskType";
13
+ import {
14
+ getInvestigationCodeFixTaskSnapshot,
15
+ InvestigationCodeFixTaskContext,
16
+ } from "../../Types/AI/CodeFixTaskContext";
12
17
  import SortOrder from "../../Types/BaseDatabase/SortOrder";
13
18
  import QueryHelper from "../Types/Database/QueryHelper";
14
19
  import CountBy from "../Types/Database/CountBy";
@@ -40,6 +45,7 @@ export interface AIRunTransitionSet {
40
45
  llmCallCount?: number | undefined;
41
46
  toolCallCount?: number | undefined;
42
47
  totalTokens?: number | undefined;
48
+ codeFixRecommendation?: AIRunCodeFixRecommendation | undefined;
43
49
  // The claiming agent's id as a string (ObjectID.toString()) — see above.
44
50
  aiAgentId?: string | undefined;
45
51
  }
@@ -52,8 +58,8 @@ export class Service extends DatabaseService<Model> {
52
58
  /*
53
59
  * A genuinely atomic status transition: one conditional UPDATE whose WHERE
54
60
  * carries the expected current status (and optionally the expected
55
- * attemptCount). Returns the number of rows changed — 0 means another
56
- * actor won the race.
61
+ * attemptCount / heartbeat snapshot). Returns the number of rows changed —
62
+ * 0 means another actor won the race or refreshed the heartbeat.
57
63
  *
58
64
  * This exists because updateOneBy is SELECT-then-save: two concurrent
59
65
  * callers can both observe the precondition and both write, so it cannot
@@ -65,6 +71,7 @@ export class Service extends DatabaseService<Model> {
65
71
  aiRunId: ObjectID;
66
72
  fromStatus: AIRunStatus;
67
73
  expectedAttemptCount?: number | undefined;
74
+ expectedLastHeartbeatAt?: Date | undefined;
68
75
  set: AIRunTransitionSet;
69
76
  }): Promise<number> {
70
77
  const queryBuilder: UpdateQueryBuilder<Model> = this.getRepository()
@@ -81,11 +88,57 @@ export class Service extends DatabaseService<Model> {
81
88
  });
82
89
  }
83
90
 
91
+ if (data.expectedLastHeartbeatAt !== undefined) {
92
+ queryBuilder.andWhere('"lastHeartbeatAt" = :expectedLastHeartbeatAt', {
93
+ expectedLastHeartbeatAt: data.expectedLastHeartbeatAt,
94
+ });
95
+ }
96
+
84
97
  const result: UpdateResult = await queryBuilder.execute();
85
98
 
86
99
  return result.affected || 0;
87
100
  }
88
101
 
102
+ /*
103
+ * Atomically settle the code-fix decision written as Pending by the
104
+ * winning investigation completion transition. The recommendation and
105
+ * immutable analysis snapshot are one database UPDATE guarded by both the
106
+ * run id and Pending state; a stale writer can never overwrite a decision
107
+ * another actor already settled.
108
+ */
109
+ @CaptureSpan()
110
+ public async finalizeInvestigationCodeFixRecommendation(
111
+ data:
112
+ | {
113
+ aiRunId: ObjectID;
114
+ recommendation: AIRunCodeFixRecommendation.Recommended;
115
+ taskContext: InvestigationCodeFixTaskContext;
116
+ }
117
+ | {
118
+ aiRunId: ObjectID;
119
+ recommendation: AIRunCodeFixRecommendation.NotRecommended;
120
+ },
121
+ ): Promise<number> {
122
+ const result: UpdateResult = await this.getRepository()
123
+ .createQueryBuilder()
124
+ .update(Model)
125
+ .set({
126
+ codeFixRecommendation: data.recommendation,
127
+ ...(data.recommendation === AIRunCodeFixRecommendation.Recommended
128
+ ? { taskContext: data.taskContext }
129
+ : {}),
130
+ } as QueryDeepPartialEntity<Model>)
131
+ .where('"_id" = :id', { id: data.aiRunId.toString() })
132
+ .andWhere('"status" = :status', { status: AIRunStatus.Completed })
133
+ .andWhere('"codeFixRecommendation" = :pending', {
134
+ pending: AIRunCodeFixRecommendation.Pending,
135
+ })
136
+ .andWhere('"deletedAt" IS NULL')
137
+ .execute();
138
+
139
+ return result.affected || 0;
140
+ }
141
+
89
142
  /*
90
143
  * Atomically claim the oldest Queued code-fix run for an external agent
91
144
  * worker (the /ai-agent-task/get-pending-task route). The Queued -> Running
@@ -193,10 +246,22 @@ export class Service extends DatabaseService<Model> {
193
246
  ? null
194
247
  : "Queued code-fix run has no telemetry exception to fix.";
195
248
  } else if (contextKind === CodeFixContextKind.IncidentOrAlertSubject) {
196
- missingContextMessage =
197
- run.triggeredByIncidentId || run.triggeredByAlertId
198
- ? null
199
- : "Queued code-fix run has no incident or alert subject.";
249
+ if (!run.triggeredByIncidentId && !run.triggeredByAlertId) {
250
+ missingContextMessage =
251
+ "Queued code-fix run has no incident or alert subject.";
252
+ } else if (
253
+ run.codeFixTaskType === CodeFixTaskType.FixFromIncident &&
254
+ !getInvestigationCodeFixTaskSnapshot(run.taskContext)
255
+ ) {
256
+ /*
257
+ * A subject alone is mutable context: a later investigation can post
258
+ * another RootCause before the worker starts. FixFromIncident must
259
+ * therefore carry the exact Recommended run + analysis it was
260
+ * authorized from. Contextless legacy rows fail closed.
261
+ */
262
+ missingContextMessage =
263
+ "Queued FixFromIncident run has no complete pinned investigation analysis snapshot.";
264
+ }
200
265
  } else if (
201
266
  run.codeFixTaskType === CodeFixTaskType.ImproveLogging ||
202
267
  run.codeFixTaskType === CodeFixTaskType.ImproveTracing
@@ -296,7 +361,7 @@ export class Service extends DatabaseService<Model> {
296
361
 
297
362
  /*
298
363
  * Measurement layer (Phase 2): record a human's one-click verdict
299
- * (Confirmed / Rejected) on the LATEST COMPLETED investigation run for an
364
+ * (Confirmed / Rejected) on one exact COMPLETED investigation run for an
300
365
  * incident or alert. Overwriting an existing verdict is deliberate — a
301
366
  * user may change their mind; the verdict is per-run state, not an audit
302
367
  * trail. Throws when no completed investigation exists for the subject.
@@ -305,7 +370,9 @@ export class Service extends DatabaseService<Model> {
305
370
  * are system-authored, so the per-user privacy pin would hide them).
306
371
  */
307
372
  @CaptureSpan()
308
- public async applyHumanVerdictToLatestInvestigation(data: {
373
+ public async applyHumanVerdictToInvestigation(data: {
374
+ aiRunId: ObjectID;
375
+ projectId: ObjectID;
309
376
  incidentId?: ObjectID | undefined;
310
377
  alertId?: ObjectID | undefined;
311
378
  verdict: AIRunHumanVerdict;
@@ -319,6 +386,8 @@ export class Service extends DatabaseService<Model> {
319
386
 
320
387
  const run: Model | null = await this.findOneBy({
321
388
  query: {
389
+ _id: data.aiRunId,
390
+ projectId: data.projectId,
322
391
  runType: AIRunType.Investigation,
323
392
  status: AIRunStatus.Completed,
324
393
  ...(data.incidentId
@@ -326,13 +395,12 @@ export class Service extends DatabaseService<Model> {
326
395
  : { triggeredByAlertId: data.alertId! }),
327
396
  },
328
397
  select: { _id: true },
329
- sort: { createdAt: SortOrder.Descending },
330
398
  props: { isRoot: true },
331
399
  });
332
400
 
333
401
  if (!run || !run.id) {
334
402
  throw new BadDataException(
335
- "No completed AI investigation exists for this subject yet a verdict can only be recorded on a completed investigation.",
403
+ "The selected completed AI investigation does not exist for this subject — refresh the page before recording a verdict.",
336
404
  );
337
405
  }
338
406