@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
@@ -0,0 +1,480 @@
1
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
2
+ import "@testing-library/jest-dom";
3
+ import { act, cleanup, render, screen, waitFor } from "@testing-library/react";
4
+ import * as React from "react";
5
+ import getJestMockFunction, { MockFunction } from "../../MockType";
6
+
7
+ /*
8
+ * IncidentFeed and AlertFeed normally load once at page mount. An AI report is
9
+ * posted later, immediately after the investigation completes, so the parent
10
+ * page now changes refreshToken when InvestigationPanel sees that report.
11
+ * These tests pin both the refresh signal and the less obvious request race:
12
+ * an older mount-time response must never overwrite the refreshed feed.
13
+ */
14
+
15
+ const getListMock: MockFunction = getJestMockFunction();
16
+ const feedRenderMock: MockFunction = getJestMockFunction();
17
+
18
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
19
+ return {
20
+ __esModule: true,
21
+ default: {
22
+ getList: (...args: Array<any>) => {
23
+ return getListMock(...args);
24
+ },
25
+ },
26
+ };
27
+ });
28
+
29
+ /* Keep the test about feed state, not markdown parsing or timeline chrome. */
30
+ jest.mock("../../../UI/Components/Feed/Feed", () => {
31
+ return {
32
+ __esModule: true,
33
+ default: (props: RenderedFeedProps): React.ReactElement => {
34
+ feedRenderMock(props);
35
+ return React.createElement(
36
+ "div",
37
+ { "data-testid": "rendered-feed" },
38
+ props.items.map((item: RenderedFeedItem): React.ReactElement => {
39
+ return React.createElement(
40
+ "div",
41
+ { key: item.key },
42
+ item.textInMarkdown,
43
+ );
44
+ }),
45
+ );
46
+ },
47
+ };
48
+ });
49
+
50
+ import AlertFeedElement from "../../../../App/FeatureSet/Dashboard/src/Components/Alert/AlertFeed";
51
+ import IncidentFeedElement from "../../../../App/FeatureSet/Dashboard/src/Components/Incident/IncidentFeed";
52
+ import AlertFeed, {
53
+ AlertFeedEventType,
54
+ } from "../../../Models/DatabaseModels/AlertFeed";
55
+ import IncidentFeed, {
56
+ IncidentFeedEventType,
57
+ } from "../../../Models/DatabaseModels/IncidentFeed";
58
+ import IconProp from "../../../Types/Icon/IconProp";
59
+ import ObjectID from "../../../Types/ObjectID";
60
+
61
+ interface RenderedFeedItem {
62
+ key: string;
63
+ textInMarkdown: string;
64
+ icon: IconProp;
65
+ safeMode?: boolean | undefined;
66
+ }
67
+
68
+ interface RenderedFeedProps {
69
+ items: Array<RenderedFeedItem>;
70
+ noItemsMessage: string;
71
+ }
72
+
73
+ interface ListResult<T> {
74
+ data: Array<T>;
75
+ count: number;
76
+ skip: number;
77
+ limit: number;
78
+ }
79
+
80
+ interface Deferred<T> {
81
+ promise: Promise<T>;
82
+ resolve: (value: T) => void;
83
+ }
84
+
85
+ interface FeedListRequest {
86
+ modelType: unknown;
87
+ query: Record<string, unknown>;
88
+ select: Record<string, unknown>;
89
+ }
90
+
91
+ const INCIDENT_ID: ObjectID = new ObjectID(
92
+ "66666666-6666-4666-8666-666666666666",
93
+ );
94
+ const ALERT_ID: ObjectID = new ObjectID("77777777-7777-4777-8777-777777777777");
95
+ const NEXT_INCIDENT_ID: ObjectID = new ObjectID(
96
+ "abababab-abab-4bab-8bab-abababababab",
97
+ );
98
+ const NEXT_ALERT_ID: ObjectID = new ObjectID(
99
+ "cdcdcdcd-cdcd-4dcd-8dcd-cdcdcdcdcdcd",
100
+ );
101
+ const AI_RUN_ID: ObjectID = new ObjectID(
102
+ "12121212-1212-4212-8212-121212121212",
103
+ );
104
+ const POSTED_AT: Date = new Date("2026-08-07T11:00:00.000Z");
105
+ const INCIDENT_ANALYSIS: string =
106
+ "## AI — Automated Root Cause Analysis\n\nThe incident was caused by connection exhaustion.";
107
+ const ALERT_ANALYSIS: string =
108
+ "## AI — Automated Root Cause Analysis\n\nThe alert was caused by a failed dependency.";
109
+ const ORDINARY_ROOT_CAUSE: string =
110
+ "## Root cause\n\nAn engineer identified a configuration regression.";
111
+
112
+ function listResult<T>(data: Array<T>): ListResult<T> {
113
+ return {
114
+ data,
115
+ count: data.length,
116
+ skip: 0,
117
+ limit: 100,
118
+ };
119
+ }
120
+
121
+ function incidentAnalysisItem(): IncidentFeed {
122
+ const item: IncidentFeed = new IncidentFeed();
123
+ item.id = new ObjectID("88888888-8888-4888-8888-888888888888");
124
+ item.incidentId = INCIDENT_ID;
125
+ item.incidentFeedEventType = IncidentFeedEventType.RootCause;
126
+ item.aiRunId = AI_RUN_ID;
127
+ item.feedInfoInMarkdown = INCIDENT_ANALYSIS;
128
+ item.postedAt = POSTED_AT;
129
+ item.createdAt = POSTED_AT;
130
+ return item;
131
+ }
132
+
133
+ function alertAnalysisItem(): AlertFeed {
134
+ const item: AlertFeed = new AlertFeed();
135
+ item.id = new ObjectID("99999999-9999-4999-8999-999999999999");
136
+ item.alertId = ALERT_ID;
137
+ item.alertFeedEventType = AlertFeedEventType.RootCause;
138
+ item.aiRunId = AI_RUN_ID;
139
+ item.feedInfoInMarkdown = ALERT_ANALYSIS;
140
+ item.postedAt = POSTED_AT;
141
+ item.createdAt = POSTED_AT;
142
+ return item;
143
+ }
144
+
145
+ function nextIncidentAnalysisItem(): IncidentFeed {
146
+ const item: IncidentFeed = incidentAnalysisItem();
147
+ item.id = new ObjectID("dededede-dede-4ede-8ede-dededededede");
148
+ item.incidentId = NEXT_INCIDENT_ID;
149
+ item.feedInfoInMarkdown =
150
+ "## AI — Automated Root Cause Analysis\n\nThe next incident has its own report.";
151
+ return item;
152
+ }
153
+
154
+ function nextAlertAnalysisItem(): AlertFeed {
155
+ const item: AlertFeed = alertAnalysisItem();
156
+ item.id = new ObjectID("efefefef-efef-4fef-8fef-efefefefefef");
157
+ item.alertId = NEXT_ALERT_ID;
158
+ item.feedInfoInMarkdown =
159
+ "## AI — Automated Root Cause Analysis\n\nThe next alert has its own report.";
160
+ return item;
161
+ }
162
+
163
+ function ordinaryIncidentRootCauseItem(): IncidentFeed {
164
+ const item: IncidentFeed = incidentAnalysisItem();
165
+ item.id = new ObjectID("aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa");
166
+ delete item.aiRunId;
167
+ item.feedInfoInMarkdown = ORDINARY_ROOT_CAUSE;
168
+ return item;
169
+ }
170
+
171
+ function ordinaryAlertRootCauseItem(): AlertFeed {
172
+ const item: AlertFeed = alertAnalysisItem();
173
+ item.id = new ObjectID("bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb");
174
+ delete item.aiRunId;
175
+ item.feedInfoInMarkdown = ORDINARY_ROOT_CAUSE;
176
+ return item;
177
+ }
178
+
179
+ function createDeferred<T>(): Deferred<T> {
180
+ let resolvePromise: ((value: T) => void) | undefined;
181
+ const promise: Promise<T> = new Promise<T>((resolve: (value: T) => void) => {
182
+ resolvePromise = resolve;
183
+ });
184
+
185
+ return {
186
+ promise,
187
+ resolve: (value: T): void => {
188
+ resolvePromise!(value);
189
+ },
190
+ };
191
+ }
192
+
193
+ function incidentElement(refreshToken: number): React.ReactElement {
194
+ return (
195
+ <IncidentFeedElement incidentId={INCIDENT_ID} refreshToken={refreshToken} />
196
+ );
197
+ }
198
+
199
+ function alertElement(refreshToken: number): React.ReactElement {
200
+ return <AlertFeedElement alertId={ALERT_ID} refreshToken={refreshToken} />;
201
+ }
202
+
203
+ async function flush(): Promise<void> {
204
+ await act(async (): Promise<void> => {
205
+ await Promise.resolve();
206
+ await Promise.resolve();
207
+ await Promise.resolve();
208
+ await Promise.resolve();
209
+ });
210
+ }
211
+
212
+ async function resolveDeferred<T>(
213
+ deferred: Deferred<T>,
214
+ value: T,
215
+ ): Promise<void> {
216
+ await act(async (): Promise<void> => {
217
+ deferred.resolve(value);
218
+ await Promise.resolve();
219
+ await Promise.resolve();
220
+ await Promise.resolve();
221
+ await Promise.resolve();
222
+ });
223
+ }
224
+
225
+ function lastRenderedFeedProps(): RenderedFeedProps {
226
+ const calls: Array<Array<RenderedFeedProps>> = feedRenderMock.mock
227
+ .calls as Array<Array<RenderedFeedProps>>;
228
+ return calls[calls.length - 1]![0]!;
229
+ }
230
+
231
+ afterEach(() => {
232
+ cleanup();
233
+ getListMock.mockReset();
234
+ feedRenderMock.mockReset();
235
+ });
236
+
237
+ describe("investigation reports in incident and alert feeds", () => {
238
+ test("refreshToken makes the incident feed fetch and show the posted report", async () => {
239
+ getListMock
240
+ .mockResolvedValueOnce(listResult<IncidentFeed>([]) as never)
241
+ .mockResolvedValueOnce(
242
+ listResult<IncidentFeed>([incidentAnalysisItem()]) as never,
243
+ );
244
+
245
+ const view: ReturnType<typeof render> = render(incidentElement(0));
246
+
247
+ await waitFor((): void => {
248
+ expect(getListMock).toHaveBeenCalledTimes(1);
249
+ });
250
+ expect(screen.queryByText(/connection exhaustion/)).toBeNull();
251
+
252
+ view.rerender(
253
+ <IncidentFeedElement
254
+ incidentId={new ObjectID(INCIDENT_ID.toString())}
255
+ refreshToken={1}
256
+ />,
257
+ );
258
+
259
+ await waitFor(
260
+ (): void => {
261
+ expect(screen.getByText(/connection exhaustion/)).toBeVisible();
262
+ },
263
+ { timeout: 10000 },
264
+ );
265
+ expect(getListMock).toHaveBeenCalledTimes(2);
266
+ expect(lastRenderedFeedProps().items[0]).toEqual(
267
+ expect.objectContaining({
268
+ icon: IconProp.Sparkles,
269
+ safeMode: true,
270
+ }),
271
+ );
272
+
273
+ const request: FeedListRequest = getListMock.mock
274
+ .calls[1]![0] as FeedListRequest;
275
+ expect(request.modelType).toBe(IncidentFeed);
276
+ expect(request.query).toEqual({ incidentId: INCIDENT_ID });
277
+ expect(request.select).toEqual(
278
+ expect.objectContaining({
279
+ feedInfoInMarkdown: true,
280
+ aiRunId: true,
281
+ incidentFeedEventType: true,
282
+ }),
283
+ );
284
+
285
+ view.rerender(incidentElement(1));
286
+ await flush();
287
+ expect(getListMock).toHaveBeenCalledTimes(2);
288
+ });
289
+
290
+ test("refreshToken makes the alert feed fetch and show the posted report", async () => {
291
+ getListMock
292
+ .mockResolvedValueOnce(listResult<AlertFeed>([]) as never)
293
+ .mockResolvedValueOnce(
294
+ listResult<AlertFeed>([alertAnalysisItem()]) as never,
295
+ );
296
+
297
+ const view: ReturnType<typeof render> = render(alertElement(10));
298
+
299
+ await waitFor((): void => {
300
+ expect(getListMock).toHaveBeenCalledTimes(1);
301
+ });
302
+ expect(screen.queryByText(/failed dependency/)).toBeNull();
303
+
304
+ view.rerender(
305
+ <AlertFeedElement
306
+ alertId={new ObjectID(ALERT_ID.toString())}
307
+ refreshToken={11}
308
+ />,
309
+ );
310
+
311
+ await waitFor(
312
+ (): void => {
313
+ expect(screen.getByText(/failed dependency/)).toBeVisible();
314
+ },
315
+ { timeout: 10000 },
316
+ );
317
+ expect(getListMock).toHaveBeenCalledTimes(2);
318
+ expect(lastRenderedFeedProps().items[0]).toEqual(
319
+ expect.objectContaining({
320
+ icon: IconProp.Sparkles,
321
+ safeMode: true,
322
+ }),
323
+ );
324
+
325
+ const request: FeedListRequest = getListMock.mock
326
+ .calls[1]![0] as FeedListRequest;
327
+ expect(request.modelType).toBe(AlertFeed);
328
+ expect(request.query).toEqual({ alertId: ALERT_ID });
329
+ expect(request.select).toEqual(
330
+ expect.objectContaining({
331
+ feedInfoInMarkdown: true,
332
+ aiRunId: true,
333
+ alertFeedEventType: true,
334
+ }),
335
+ );
336
+
337
+ view.rerender(alertElement(11));
338
+ await flush();
339
+ expect(getListMock).toHaveBeenCalledTimes(2);
340
+ });
341
+
342
+ test("a late mount-time incident response cannot erase the refreshed report", async () => {
343
+ const initialRequest: Deferred<ListResult<IncidentFeed>> =
344
+ createDeferred<ListResult<IncidentFeed>>();
345
+ const refreshedRequest: Deferred<ListResult<IncidentFeed>> =
346
+ createDeferred<ListResult<IncidentFeed>>();
347
+
348
+ getListMock
349
+ .mockReturnValueOnce(initialRequest.promise as never)
350
+ .mockReturnValueOnce(refreshedRequest.promise as never);
351
+
352
+ const view: ReturnType<typeof render> = render(incidentElement(0));
353
+ await flush();
354
+ expect(getListMock).toHaveBeenCalledTimes(1);
355
+
356
+ view.rerender(incidentElement(1));
357
+ await flush();
358
+ expect(getListMock).toHaveBeenCalledTimes(2);
359
+
360
+ await resolveDeferred(
361
+ refreshedRequest,
362
+ listResult<IncidentFeed>([incidentAnalysisItem()]),
363
+ );
364
+ expect(screen.getByText(/connection exhaustion/)).toBeVisible();
365
+
366
+ /* The older empty result arrives last and must be ignored. */
367
+ await resolveDeferred(initialRequest, listResult<IncidentFeed>([]));
368
+ expect(screen.getByText(/connection exhaustion/)).toBeVisible();
369
+ });
370
+
371
+ test("a late mount-time alert response cannot erase the refreshed report", async () => {
372
+ const initialRequest: Deferred<ListResult<AlertFeed>> =
373
+ createDeferred<ListResult<AlertFeed>>();
374
+ const refreshedRequest: Deferred<ListResult<AlertFeed>> =
375
+ createDeferred<ListResult<AlertFeed>>();
376
+
377
+ getListMock
378
+ .mockReturnValueOnce(initialRequest.promise as never)
379
+ .mockReturnValueOnce(refreshedRequest.promise as never);
380
+
381
+ const view: ReturnType<typeof render> = render(alertElement(20));
382
+ await flush();
383
+ expect(getListMock).toHaveBeenCalledTimes(1);
384
+
385
+ view.rerender(alertElement(21));
386
+ await flush();
387
+ expect(getListMock).toHaveBeenCalledTimes(2);
388
+
389
+ await resolveDeferred(
390
+ refreshedRequest,
391
+ listResult<AlertFeed>([alertAnalysisItem()]),
392
+ );
393
+ expect(screen.getByText(/failed dependency/)).toBeVisible();
394
+
395
+ await resolveDeferred(initialRequest, listResult<AlertFeed>([]));
396
+ expect(screen.getByText(/failed dependency/)).toBeVisible();
397
+ });
398
+
399
+ test("subject navigation never paints the previous incident or alert feed", async () => {
400
+ const nextIncidentRequest: Deferred<ListResult<IncidentFeed>> =
401
+ createDeferred<ListResult<IncidentFeed>>();
402
+ getListMock
403
+ .mockResolvedValueOnce(
404
+ listResult<IncidentFeed>([incidentAnalysisItem()]) as never,
405
+ )
406
+ .mockReturnValueOnce(nextIncidentRequest.promise as never);
407
+
408
+ const incidentView: ReturnType<typeof render> = render(incidentElement(0));
409
+ expect(await screen.findByText(/connection exhaustion/)).toBeVisible();
410
+
411
+ incidentView.rerender(
412
+ <IncidentFeedElement incidentId={NEXT_INCIDENT_ID} refreshToken={0} />,
413
+ );
414
+ expect(screen.queryByText(/connection exhaustion/)).toBeNull();
415
+ await flush();
416
+ expect(getListMock).toHaveBeenCalledTimes(2);
417
+
418
+ await resolveDeferred(
419
+ nextIncidentRequest,
420
+ listResult<IncidentFeed>([nextIncidentAnalysisItem()]),
421
+ );
422
+ expect(screen.getByText(/next incident has its own report/)).toBeVisible();
423
+
424
+ incidentView.unmount();
425
+ getListMock.mockClear();
426
+
427
+ const nextAlertRequest: Deferred<ListResult<AlertFeed>> =
428
+ createDeferred<ListResult<AlertFeed>>();
429
+ getListMock
430
+ .mockResolvedValueOnce(
431
+ listResult<AlertFeed>([alertAnalysisItem()]) as never,
432
+ )
433
+ .mockReturnValueOnce(nextAlertRequest.promise as never);
434
+
435
+ const alertView: ReturnType<typeof render> = render(alertElement(0));
436
+ expect(await screen.findByText(/failed dependency/)).toBeVisible();
437
+
438
+ alertView.rerender(
439
+ <AlertFeedElement alertId={NEXT_ALERT_ID} refreshToken={0} />,
440
+ );
441
+ expect(screen.queryByText(/failed dependency/)).toBeNull();
442
+ await flush();
443
+ expect(getListMock).toHaveBeenCalledTimes(2);
444
+
445
+ await resolveDeferred(
446
+ nextAlertRequest,
447
+ listResult<AlertFeed>([nextAlertAnalysisItem()]),
448
+ );
449
+ expect(screen.getByText(/next alert has its own report/)).toBeVisible();
450
+ });
451
+
452
+ test("ordinary incident and alert root causes keep their standard rendering", async () => {
453
+ getListMock.mockResolvedValueOnce(
454
+ listResult<IncidentFeed>([ordinaryIncidentRootCauseItem()]) as never,
455
+ );
456
+
457
+ const incidentView: ReturnType<typeof render> = render(incidentElement(0));
458
+ expect(await screen.findByText(/configuration regression/)).toBeVisible();
459
+ expect(lastRenderedFeedProps().items[0]).toEqual(
460
+ expect.objectContaining({
461
+ icon: IconProp.Cube,
462
+ safeMode: false,
463
+ }),
464
+ );
465
+
466
+ incidentView.unmount();
467
+ getListMock.mockResolvedValueOnce(
468
+ listResult<AlertFeed>([ordinaryAlertRootCauseItem()]) as never,
469
+ );
470
+
471
+ render(alertElement(0));
472
+ expect(await screen.findByText(/configuration regression/)).toBeVisible();
473
+ expect(lastRenderedFeedProps().items[0]).toEqual(
474
+ expect.objectContaining({
475
+ icon: IconProp.Cube,
476
+ safeMode: false,
477
+ }),
478
+ );
479
+ });
480
+ });