@oneuptime/common 13.0.8 → 14.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (514) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +23 -15
  2. package/Models/DatabaseModels/GlobalConfig.ts +24 -0
  3. package/Models/DatabaseModels/Index.ts +4 -0
  4. package/Models/DatabaseModels/Monitor.ts +3 -2
  5. package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
  6. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +2 -0
  7. package/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.ts +522 -0
  8. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +38 -4
  9. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.ts +603 -0
  10. package/Scripts/generate-service-worker.js +65 -4
  11. package/Server/API/BaseAPI.ts +26 -5
  12. package/Server/API/GlobalConfigAPI.ts +228 -462
  13. package/Server/API/ProjectOIDC.ts +25 -16
  14. package/Server/API/ProjectSSO.ts +24 -16
  15. package/Server/API/StatusPageAPI.ts +100 -42
  16. package/Server/API/TeamMemberAPI.ts +10 -1
  17. package/Server/Enterprise/EnterpriseEdition.ts +649 -0
  18. package/Server/Enterprise/EnterpriseFeature.ts +48 -0
  19. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
  20. package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
  21. package/Server/EnvironmentConfig.ts +147 -2
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.ts +248 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.ts +19 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  26. package/Server/Middleware/UserAuthorization.ts +38 -16
  27. package/Server/Services/AuditLogService.ts +84 -1079
  28. package/Server/Services/DatabaseService.ts +10 -0
  29. package/Server/Services/EnterpriseLicenseService.ts +38 -0
  30. package/Server/Services/GlobalConfigService.ts +80 -1
  31. package/Server/Services/Index.ts +4 -0
  32. package/Server/Services/MonitorProbeService.ts +116 -20
  33. package/Server/Services/MonitorService.ts +59 -6
  34. package/Server/Services/MonitorStatusTimelineService.ts +284 -0
  35. package/Server/Services/MonitorTemplateService.ts +26 -0
  36. package/Server/Services/ProjectService.ts +284 -0
  37. package/Server/Services/RumSessionPinService.ts +25 -6
  38. package/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.ts +385 -0
  39. package/Server/Services/ServiceLevelObjectiveLabelRuleService.ts +51 -0
  40. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +92 -16
  41. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +36 -1
  42. package/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.ts +521 -0
  43. package/Server/Services/ServiceLevelObjectiveOwnerRuleService.ts +51 -0
  44. package/Server/Services/ServiceLevelObjectiveService.ts +28 -0
  45. package/Server/Services/StatusPagePrivateUserService.ts +7 -3
  46. package/Server/Services/StatusPageService.ts +78 -1
  47. package/Server/Services/TeamMemberService.ts +11 -0
  48. package/Server/Services/TeamService.ts +10 -0
  49. package/Server/Services/UserService.ts +10 -17
  50. package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
  51. package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
  52. package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
  53. package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
  54. package/Server/Types/Markdown.ts +41 -0
  55. package/Server/Types/Workflow/Components/Telegram/SendMessageToChat.ts +27 -1
  56. package/Server/Utils/AI/Toolbox/SloTools.ts +1 -0
  57. package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
  58. package/Server/Utils/EditionEnforcement.ts +233 -0
  59. package/Server/Utils/FrontendEnvironment.ts +41 -2
  60. package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
  61. package/Server/Utils/Monitor/AffectedResourceList.ts +148 -0
  62. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +1 -1
  63. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
  64. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +1 -1
  65. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +720 -465
  66. package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
  67. package/Server/Utils/Monitor/RootCauseList.ts +139 -0
  68. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +28 -0
  69. package/Server/Utils/Slo/SloRulePatternValidator.ts +42 -0
  70. package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
  71. package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
  72. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
  73. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
  74. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
  75. package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
  76. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
  77. package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
  78. package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
  79. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
  80. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
  81. package/Tests/App/Dashboard/FeedFilterSortIntegration.test.tsx +1632 -0
  82. package/Tests/App/Dashboard/FeedOptionsLocales.test.ts +250 -0
  83. package/Tests/App/Dashboard/FeedOrdering.test.ts +279 -9
  84. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
  85. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +60 -1
  86. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +594 -3
  87. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
  88. package/Tests/App/Dashboard/ProductOrientation.test.tsx +646 -0
  89. package/Tests/App/Dashboard/ResourceFeed.test.tsx +612 -2
  90. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +30 -0
  91. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +1202 -0
  92. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +52 -1
  93. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
  94. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
  95. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
  96. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
  97. package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
  98. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
  99. package/Tests/App/Dashboard/SloFeed.test.tsx +106 -1
  100. package/Tests/App/Dashboard/SloMonitorRuleCriteria.test.tsx +566 -0
  101. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +6 -4
  102. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +186 -0
  103. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +388 -44
  104. package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +613 -0
  105. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
  106. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
  107. package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
  108. package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
  109. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +0 -8
  110. package/Tests/Models/DatabaseModels/SloLabelAndOwnerRuleModels.test.ts +404 -0
  111. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +17 -1
  112. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  113. package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
  114. package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
  115. package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
  116. package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
  117. package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
  118. package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
  119. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
  120. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
  121. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
  122. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
  123. package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
  124. package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
  125. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
  126. package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
  127. package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
  128. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
  129. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
  130. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  131. package/Tests/Server/Infrastructure/Postgres/AddSloLabelAndOwnerRulesMigration.test.ts +407 -0
  132. package/Tests/Server/Infrastructure/Postgres/AddSloMonitorRuleMonitorTypeMigration.test.ts +171 -0
  133. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +88 -4
  134. package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
  135. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
  136. package/Tests/Server/Services/AuditLogService.test.ts +460 -990
  137. package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
  138. package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +104 -0
  139. package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
  140. package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
  141. package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
  142. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
  143. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
  144. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
  145. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
  146. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +48 -1
  147. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -0
  148. package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
  149. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +1170 -0
  150. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleServices.test.ts +172 -0
  151. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +323 -0
  152. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +115 -0
  153. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleTriggers.test.ts +21 -2
  154. package/Tests/Server/Services/ServiceLevelObjectiveMonitorTypePostgres.test.ts +480 -0
  155. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +162 -0
  156. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
  157. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
  158. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +45 -6
  159. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
  160. package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
  161. package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
  162. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +745 -0
  163. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
  164. package/Tests/Server/Types/Markdown.test.ts +183 -1
  165. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +49 -0
  166. package/Tests/Server/Types/Workflow/Components/TelegramSendMessageToChat.test.ts +331 -0
  167. package/Tests/Server/Utils/AI/SloTools.test.ts +10 -0
  168. package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
  169. package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
  170. package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
  171. package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
  172. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
  173. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
  174. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +1 -1
  175. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +1339 -96
  176. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +1101 -0
  177. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +106 -80
  178. package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
  179. package/Tests/Server/Utils/Monitor/RootCauseList.test.ts +252 -0
  180. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +154 -0
  181. package/Tests/Server/Utils/SSRFProtection.test.ts +111 -0
  182. package/Tests/Server/Utils/Slo/SloRulePatternValidator.test.ts +67 -0
  183. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +213 -0
  184. package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
  185. package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
  186. package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
  187. package/Tests/Types/API/Route.test.ts +56 -0
  188. package/Tests/Types/API/URLSchemeLikePath.test.ts +304 -0
  189. package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
  190. package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
  191. package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
  192. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
  193. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
  194. package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
  195. package/Tests/UI/Components/FeedOptions.test.ts +1404 -0
  196. package/Tests/UI/Components/FeedOptionsButton.test.tsx +2603 -0
  197. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
  198. package/Tests/UI/Components/Icon.test.tsx +26 -0
  199. package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
  200. package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
  201. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  202. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
  203. package/Tests/UI/Components/useFeedItemsViewKey.test.tsx +1017 -0
  204. package/Tests/UI/Components/useFeedOptions.test.tsx +1107 -0
  205. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
  206. package/Tests/Utils/HostAddressUtil.test.ts +138 -0
  207. package/Tests/Utils/LabelRuleImportExport.test.ts +102 -0
  208. package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
  209. package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
  210. package/Tests/Utils/Slo/SloDuration.test.ts +115 -24
  211. package/Tests/Utils/Slo/SloHealth.test.ts +93 -10
  212. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +109 -0
  213. package/Tests/Utils/Slo/SloOverviewText.test.ts +64 -0
  214. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
  215. package/Types/API/Hostname.ts +63 -16
  216. package/Types/API/Route.ts +19 -2
  217. package/Types/API/URL.ts +26 -2
  218. package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
  219. package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
  220. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
  221. package/Types/Database/CanonicalModelInstance.ts +102 -0
  222. package/Types/Database/TableColumn.ts +20 -6
  223. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
  224. package/Types/IP/IPv6.ts +6 -1
  225. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +6 -5
  226. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +9 -0
  227. package/Types/Monitor/MonitorStep.ts +6 -1
  228. package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
  229. package/Types/Permission.ts +90 -0
  230. package/Types/Rules/RuleCriteriaFieldRegistry.ts +11 -0
  231. package/Types/Rules/RuleRun.ts +4 -0
  232. package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
  233. package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
  234. package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
  235. package/UI/Components/Feed/FeedOptions.ts +427 -0
  236. package/UI/Components/Feed/FeedOptionsButton.tsx +692 -0
  237. package/UI/Components/Feed/useFeedItems.ts +28 -9
  238. package/UI/Components/Feed/useFeedOptions.ts +225 -0
  239. package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
  240. package/UI/Components/Icon/Icon.tsx +1 -1
  241. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  242. package/UI/Components/ModelList/ModelList.tsx +11 -1
  243. package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
  244. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
  245. package/UI/esbuild-enterprise.js +263 -0
  246. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
  247. package/Utils/HostAddressUtil.ts +94 -0
  248. package/Utils/LabelRuleImportExport.ts +27 -9
  249. package/Utils/Monitor/MetricValueFormatter.ts +2 -2
  250. package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
  251. package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
  252. package/Utils/Rules/MonitorTypeRuleCriteria.ts +31 -0
  253. package/Utils/Slo/SloDuration.ts +22 -6
  254. package/Utils/Slo/SloHealth.ts +8 -7
  255. package/Utils/Slo/SloMonitorRuleCriteria.ts +33 -1
  256. package/Utils/Slo/SloOverviewText.ts +33 -0
  257. package/Utils/Slo/SloProjection.ts +4 -3
  258. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
  259. package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
  260. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  261. package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
  262. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  263. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  264. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  265. package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
  266. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  267. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
  268. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  269. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +2 -0
  270. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -1
  271. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js +530 -0
  272. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js.map +1 -0
  273. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +39 -4
  274. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -1
  275. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js +612 -0
  276. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js.map +1 -0
  277. package/build/dist/Server/API/BaseAPI.js +26 -5
  278. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  279. package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
  280. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  281. package/build/dist/Server/API/ProjectOIDC.js +24 -16
  282. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  283. package/build/dist/Server/API/ProjectSSO.js +24 -16
  284. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  285. package/build/dist/Server/API/StatusPageAPI.js +93 -43
  286. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  287. package/build/dist/Server/API/TeamMemberAPI.js +8 -1
  288. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  289. package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
  290. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
  291. package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
  292. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
  293. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
  294. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
  295. package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
  296. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
  297. package/build/dist/Server/EnvironmentConfig.js +84 -2
  298. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  299. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
  300. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
  301. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js +93 -0
  302. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js.map +1 -0
  303. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js +12 -0
  304. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js.map +1 -0
  305. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  306. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  307. package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
  308. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  309. package/build/dist/Server/Services/AuditLogService.js +71 -740
  310. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  311. package/build/dist/Server/Services/DatabaseService.js +7 -0
  312. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  313. package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
  314. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  315. package/build/dist/Server/Services/GlobalConfigService.js +63 -0
  316. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  317. package/build/dist/Server/Services/Index.js +4 -0
  318. package/build/dist/Server/Services/Index.js.map +1 -1
  319. package/build/dist/Server/Services/MonitorProbeService.js +90 -17
  320. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  321. package/build/dist/Server/Services/MonitorService.js +48 -6
  322. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  323. package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
  324. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  325. package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
  326. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  327. package/build/dist/Server/Services/ProjectService.js +214 -0
  328. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  329. package/build/dist/Server/Services/RumSessionPinService.js +24 -6
  330. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  331. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js +295 -0
  332. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js.map +1 -0
  333. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js +56 -0
  334. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js.map +1 -0
  335. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +59 -14
  336. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  337. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +22 -1
  338. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -1
  339. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js +400 -0
  340. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js.map +1 -0
  341. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js +56 -0
  342. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js.map +1 -0
  343. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +21 -0
  344. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  345. package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
  346. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  347. package/build/dist/Server/Services/StatusPageService.js +71 -0
  348. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  349. package/build/dist/Server/Services/TeamMemberService.js +10 -0
  350. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  351. package/build/dist/Server/Services/TeamService.js +9 -0
  352. package/build/dist/Server/Services/TeamService.js.map +1 -1
  353. package/build/dist/Server/Services/UserService.js +10 -16
  354. package/build/dist/Server/Services/UserService.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
  356. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
  358. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
  360. package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
  361. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
  362. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  363. package/build/dist/Server/Types/Markdown.js +31 -0
  364. package/build/dist/Server/Types/Markdown.js.map +1 -1
  365. package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js +20 -1
  366. package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +1 -0
  368. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  369. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
  370. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
  371. package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
  372. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
  373. package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
  374. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
  375. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
  376. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
  377. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +67 -0
  378. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
  379. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +1 -1
  380. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  381. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  382. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +1 -1
  383. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +585 -367
  384. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  385. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
  386. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
  387. package/build/dist/Server/Utils/Monitor/RootCauseList.js +101 -0
  388. package/build/dist/Server/Utils/Monitor/RootCauseList.js.map +1 -0
  389. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +28 -0
  390. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  391. package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js +28 -0
  392. package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js.map +1 -0
  393. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
  394. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  395. package/build/dist/Types/API/Hostname.js +59 -11
  396. package/build/dist/Types/API/Hostname.js.map +1 -1
  397. package/build/dist/Types/API/Route.js +18 -2
  398. package/build/dist/Types/API/Route.js.map +1 -1
  399. package/build/dist/Types/API/URL.js +23 -2
  400. package/build/dist/Types/API/URL.js.map +1 -1
  401. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
  402. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
  403. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
  404. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
  405. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
  406. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
  407. package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
  408. package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
  409. package/build/dist/Types/Database/TableColumn.js +19 -6
  410. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  411. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
  412. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
  413. package/build/dist/Types/IP/IPv6.js +6 -1
  414. package/build/dist/Types/IP/IPv6.js.map +1 -1
  415. package/build/dist/Types/Monitor/MonitorStep.js +5 -0
  416. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  417. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
  418. package/build/dist/Types/Permission.js +84 -0
  419. package/build/dist/Types/Permission.js.map +1 -1
  420. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +11 -0
  421. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  422. package/build/dist/Types/Rules/RuleRun.js +4 -0
  423. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  424. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
  425. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
  426. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
  427. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  428. package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
  429. package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
  430. package/build/dist/UI/Components/Feed/FeedOptions.js +235 -0
  431. package/build/dist/UI/Components/Feed/FeedOptions.js.map +1 -0
  432. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +346 -0
  433. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -0
  434. package/build/dist/UI/Components/Feed/useFeedItems.js +17 -7
  435. package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -1
  436. package/build/dist/UI/Components/Feed/useFeedOptions.js +130 -0
  437. package/build/dist/UI/Components/Feed/useFeedOptions.js.map +1 -0
  438. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
  439. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  440. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  441. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  442. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  443. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  444. package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
  445. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  446. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
  447. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  448. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
  449. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  450. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
  451. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  452. package/build/dist/Utils/HostAddressUtil.js +80 -0
  453. package/build/dist/Utils/HostAddressUtil.js.map +1 -0
  454. package/build/dist/Utils/LabelRuleImportExport.js +22 -6
  455. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  456. package/build/dist/Utils/Monitor/MetricValueFormatter.js +2 -2
  457. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
  458. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
  459. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
  460. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
  461. package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js +18 -0
  462. package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js.map +1 -0
  463. package/build/dist/Utils/Slo/SloDuration.js +13 -5
  464. package/build/dist/Utils/Slo/SloDuration.js.map +1 -1
  465. package/build/dist/Utils/Slo/SloHealth.js +8 -7
  466. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  467. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +16 -1
  468. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -1
  469. package/build/dist/Utils/Slo/SloOverviewText.js +16 -0
  470. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -1
  471. package/build/dist/Utils/Slo/SloProjection.js.map +1 -1
  472. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  473. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
  474. package/jest.config.json +3 -1
  475. package/package.json +1 -1
  476. package/test-setup.sh +103 -34
  477. package/tsconfig.json +13 -0
  478. package/Server/API/EnterpriseLicenseAPI.ts +0 -925
  479. package/Server/API/TeamComplianceAPI.ts +0 -158
  480. package/Server/Middleware/SCIMAuthorization.ts +0 -141
  481. package/Server/Services/TeamComplianceService.ts +0 -733
  482. package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
  483. package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
  484. package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
  485. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
  486. package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
  487. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
  488. package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
  489. package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
  490. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
  491. package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
  492. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
  493. package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
  494. package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
  495. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
  496. package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
  497. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
  498. package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
  499. package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
  500. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
  501. package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
  502. package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
  503. package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
  504. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
  505. package/build/dist/Server/Services/TeamComplianceService.js +0 -537
  506. package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
  507. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
  508. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
  509. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
  510. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
  511. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
  512. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
  513. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
  514. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
@@ -723,7 +723,7 @@ describe("InvestigationPanel report lifecycle", () => {
723
723
  expect(onAnalysisAvailable).toHaveBeenCalledTimes(1);
724
724
  });
725
725
 
726
- test("shows the no-report outcome and disables analysis-only actions", async () => {
726
+ test("shows the no-report outcome, disables the fix action and offers no rating", async () => {
727
727
  postMock.mockResolvedValue(
728
728
  completedResponse({
729
729
  analysisMarkdown: null,
@@ -757,8 +757,10 @@ describe("InvestigationPanel report lifecycle", () => {
757
757
  "0 telemetry queries",
758
758
  );
759
759
  expect(fixButton()).toBeDisabled();
760
- expect(screen.getByRole("button", { name: "Confirmed" })).toBeDisabled();
761
- expect(screen.getByRole("button", { name: "Rejected" })).toBeDisabled();
760
+ // There is no report to judge, so the rating row is left out entirely.
761
+ expect(screen.queryByText("Rate this investigation")).toBeNull();
762
+ expect(screen.queryByRole("button", { name: "Confirmed" })).toBeNull();
763
+ expect(screen.queryByRole("button", { name: "Rejected" })).toBeNull();
762
764
  });
763
765
 
764
766
  test("shows a terminal failure without completed actions", async () => {
@@ -1374,6 +1376,595 @@ describe("InvestigationPanel verdict control", () => {
1374
1376
  });
1375
1377
  });
1376
1378
 
1379
+ /*
1380
+ * A verdict judges the report on screen. The rating row used to render for
1381
+ * every completed run and disable both answers whenever there was no report
1382
+ * (still being prepared, finished without one, or dropped on a later poll),
1383
+ * which asked a question nobody could answer. It is now left out in all of
1384
+ * those states, the frame around the completed-run actions is not drawn
1385
+ * empty, and the only time the answers are disabled is while a save is in
1386
+ * flight.
1387
+ */
1388
+ describe("InvestigationPanel rating availability", () => {
1389
+ function ratingHeading(): HTMLElement | null {
1390
+ return screen.queryByRole("heading", { name: "Rate this investigation" });
1391
+ }
1392
+
1393
+ function ratingGroup(): HTMLElement | null {
1394
+ return screen.queryByRole("group", { name: "Rate this investigation" });
1395
+ }
1396
+
1397
+ function actionsFrame(): HTMLElement | null {
1398
+ return screen.queryByTestId("investigation-actions");
1399
+ }
1400
+
1401
+ function verdictAnswers(): Array<HTMLButtonElement> {
1402
+ return screen.queryAllByRole("button", {
1403
+ name: /^(Confirmed|Rejected)$/,
1404
+ }) as Array<HTMLButtonElement>;
1405
+ }
1406
+
1407
+ function disabledVerdictAnswers(): Array<string> {
1408
+ return verdictAnswers()
1409
+ .filter((button: HTMLButtonElement): boolean => {
1410
+ return button.disabled;
1411
+ })
1412
+ .map((button: HTMLButtonElement): string => {
1413
+ return (button.textContent || "").trim();
1414
+ });
1415
+ }
1416
+
1417
+ function expectNoRating(): void {
1418
+ expect(ratingHeading()).toBeNull();
1419
+ expect(screen.queryByText("Rate this investigation")).toBeNull();
1420
+ expect(ratingGroup()).toBeNull();
1421
+ expect(verdictAnswers()).toEqual([]);
1422
+ expect(screen.queryByText(/You (confirmed|rejected) this/)).toBeNull();
1423
+ expect(screen.queryByRole("button", { name: "Change" })).toBeNull();
1424
+ expect(screen.queryByText(/Your verdict helps measure/)).toBeNull();
1425
+ }
1426
+
1427
+ function expectRatingOffered(): void {
1428
+ expect(ratingHeading()).toBeVisible();
1429
+ const group: HTMLElement | null = ratingGroup();
1430
+ expect(group).not.toBeNull();
1431
+ expect(
1432
+ within(group!).getByRole("button", { name: "Confirmed" }),
1433
+ ).toBeEnabled();
1434
+ expect(
1435
+ within(group!).getByRole("button", { name: "Rejected" }),
1436
+ ).toBeEnabled();
1437
+ expect(actionsFrame()).toContainElement(group);
1438
+ }
1439
+
1440
+ function noReportResponse(
1441
+ overrides: Partial<InvestigationPayloadOptions> = {},
1442
+ ): ApiResponse {
1443
+ return completedResponse({
1444
+ analysisMarkdown: null,
1445
+ isAnalysisPending: false,
1446
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1447
+ ...overrides,
1448
+ });
1449
+ }
1450
+
1451
+ /*
1452
+ * An API replica from before the report was published alongside the run
1453
+ * sends neither `analysisMarkdown` nor `isAnalysisPending`, so the panel
1454
+ * reads it as complete with nothing to show.
1455
+ */
1456
+ function legacyCompletedResponse(): ApiResponse {
1457
+ return successfulResponse({
1458
+ run: {
1459
+ _id: RUN_ID,
1460
+ status: AIRunStatus.Completed,
1461
+ errorMessage: null,
1462
+ toolCallCount: 1,
1463
+ totalTokens: 10,
1464
+ humanVerdict: null,
1465
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1466
+ completedAt: COMPLETED_AT,
1467
+ },
1468
+ events: [activityEvent],
1469
+ });
1470
+ }
1471
+
1472
+ test("offers no rating while the report is being prepared, then enabled answers once it lands", async () => {
1473
+ postMock
1474
+ .mockResolvedValueOnce(
1475
+ completedResponse({
1476
+ analysisMarkdown: null,
1477
+ isAnalysisPending: true,
1478
+ codeFixRecommendation: AIRunCodeFixRecommendation.Pending,
1479
+ }) as never,
1480
+ )
1481
+ .mockResolvedValueOnce(
1482
+ completedResponse({
1483
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1484
+ }) as never,
1485
+ );
1486
+
1487
+ renderPanel();
1488
+ await flush();
1489
+
1490
+ expect(screen.getByText("Preparing the final report")).toBeVisible();
1491
+ expectNoRating();
1492
+ // Nothing is decided yet, so no empty frame is drawn under the notice.
1493
+ expect(actionsFrame()).toBeNull();
1494
+ expect(fixButton()).toBeNull();
1495
+
1496
+ await tick(POLL_INTERVAL_MS);
1497
+
1498
+ expect(postMock).toHaveBeenCalledTimes(2);
1499
+ expect(screen.getByTestId("investigation-markdown")).toHaveTextContent(
1500
+ "The database connection pool was exhausted.",
1501
+ );
1502
+ expectRatingOffered();
1503
+ });
1504
+
1505
+ test.each([
1506
+ ["incident", INCIDENT_ID, "/ai-investigation/incident"],
1507
+ ["alert", ALERT_ID, "/ai-investigation/alert"],
1508
+ ] as Array<[InvestigationSubjectType, ObjectID, string]>)(
1509
+ "offers no rating on an %s whose run finished without a report",
1510
+ async (
1511
+ subjectType: InvestigationSubjectType,
1512
+ subjectId: ObjectID,
1513
+ path: string,
1514
+ ) => {
1515
+ postMock.mockResolvedValue(noReportResponse() as never);
1516
+
1517
+ renderPanel({ subjectType, subjectId });
1518
+ await flush();
1519
+
1520
+ expect(requestPath(0)).toContain(path);
1521
+ expect(
1522
+ screen.getByText("Investigation completed without a report"),
1523
+ ).toBeVisible();
1524
+ expect(
1525
+ screen.getByText("No investigation report was published."),
1526
+ ).toBeVisible();
1527
+ expectNoRating();
1528
+ expect(actionsFrame()).toBeNull();
1529
+ // The run's own working is still there to read.
1530
+ expect(detailsToggle()).toHaveTextContent("Investigation activity");
1531
+ },
1532
+ );
1533
+
1534
+ test("does not show a verdict stored on a run that has no report", async () => {
1535
+ const onVerdictChange: MockFunction = getJestMockFunction();
1536
+ postMock.mockResolvedValue(
1537
+ noReportResponse({ humanVerdict: AIRunHumanVerdict.Confirmed }) as never,
1538
+ );
1539
+
1540
+ renderPanel({ onVerdictChange });
1541
+ await flush();
1542
+
1543
+ expectNoRating();
1544
+ expect(actionsFrame()).toBeNull();
1545
+ // The header leaves it out on the same terms.
1546
+ expect(
1547
+ onVerdictChange.mock.calls.filter((call: Array<unknown>): boolean => {
1548
+ return call[0] !== null;
1549
+ }),
1550
+ ).toEqual([]);
1551
+ });
1552
+
1553
+ test("keeps a Recommended fix action in its frame without a rating row beside it", async () => {
1554
+ postMock.mockResolvedValue(
1555
+ completedResponse({
1556
+ analysisMarkdown: null,
1557
+ isAnalysisPending: false,
1558
+ codeFixRecommendation: AIRunCodeFixRecommendation.Recommended,
1559
+ }) as never,
1560
+ );
1561
+
1562
+ renderPanel();
1563
+ await flush();
1564
+
1565
+ const frame: HTMLElement | null = actionsFrame();
1566
+ expect(frame).not.toBeNull();
1567
+ expect(
1568
+ within(frame!).getByRole("heading", {
1569
+ name: "Act on this investigation",
1570
+ }),
1571
+ ).toBeVisible();
1572
+ expect(within(frame!).getAllByRole("heading")).toHaveLength(1);
1573
+ expectNoRating();
1574
+ });
1575
+
1576
+ test("an API replica that predates report publication offers no rating", async () => {
1577
+ postMock.mockResolvedValue(legacyCompletedResponse() as never);
1578
+
1579
+ renderPanel();
1580
+ await flush();
1581
+
1582
+ expect(screen.getByLabelText("Investigation status")).toHaveTextContent(
1583
+ "Investigation complete",
1584
+ );
1585
+ expect(
1586
+ screen.getByText("No investigation report was published."),
1587
+ ).toBeVisible();
1588
+ expectNoRating();
1589
+ expect(actionsFrame()).toBeNull();
1590
+ });
1591
+
1592
+ test("a whitespace-only report is no report to rate", async () => {
1593
+ postMock.mockResolvedValue(
1594
+ noReportResponse({ analysisMarkdown: " \n\t \n " }) as never,
1595
+ );
1596
+
1597
+ renderPanel();
1598
+ await flush();
1599
+
1600
+ expect(screen.queryByTestId("investigation-markdown")).toBeNull();
1601
+ expect(
1602
+ screen.getByText("No investigation report was published."),
1603
+ ).toBeVisible();
1604
+ expectNoRating();
1605
+ expect(actionsFrame()).toBeNull();
1606
+ });
1607
+
1608
+ test.each(
1609
+ Object.values(AIRunStatus).filter((status: AIRunStatus): boolean => {
1610
+ return status !== AIRunStatus.Completed;
1611
+ }),
1612
+ )(
1613
+ "offers no rating for a %s run, even when a report string comes with it",
1614
+ async (status: AIRunStatus) => {
1615
+ postMock.mockResolvedValue(
1616
+ successfulResponse(
1617
+ investigationPayload({
1618
+ status,
1619
+ analysisMarkdown: ANALYSIS,
1620
+ humanVerdict: AIRunHumanVerdict.Rejected,
1621
+ codeFixRecommendation: AIRunCodeFixRecommendation.Recommended,
1622
+ events: [activityEvent],
1623
+ }),
1624
+ ) as never,
1625
+ );
1626
+
1627
+ renderPanel();
1628
+ await flush();
1629
+
1630
+ expect(screen.getByLabelText("Investigation status")).toBeVisible();
1631
+ expectNoRating();
1632
+ expect(actionsFrame()).toBeNull();
1633
+ expect(fixButton()).toBeNull();
1634
+ },
1635
+ );
1636
+
1637
+ test("removes the rating when the report disappears and restores the stored verdict when it returns", async () => {
1638
+ postMock
1639
+ .mockResolvedValueOnce(
1640
+ completedResponse({
1641
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1642
+ }) as never,
1643
+ )
1644
+ .mockResolvedValueOnce(
1645
+ noReportResponse({ humanVerdict: AIRunHumanVerdict.Rejected }) as never,
1646
+ )
1647
+ .mockResolvedValueOnce(
1648
+ completedResponse({
1649
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1650
+ humanVerdict: AIRunHumanVerdict.Rejected,
1651
+ }) as never,
1652
+ );
1653
+
1654
+ renderPanel();
1655
+ await flush();
1656
+ expectRatingOffered();
1657
+
1658
+ await tick(SETTLED_POLL_INTERVAL_MS);
1659
+
1660
+ expect(postMock).toHaveBeenCalledTimes(2);
1661
+ expect(
1662
+ screen.getByText("No investigation report was published."),
1663
+ ).toBeVisible();
1664
+ expectNoRating();
1665
+ expect(actionsFrame()).toBeNull();
1666
+
1667
+ await tick(SETTLED_POLL_INTERVAL_MS);
1668
+
1669
+ expect(postMock).toHaveBeenCalledTimes(3);
1670
+ expect(ratingHeading()).toBeVisible();
1671
+ expect(screen.getByText(/You rejected this analysis/)).toBeVisible();
1672
+ expect(screen.getByRole("button", { name: "Change" })).toBeVisible();
1673
+ });
1674
+
1675
+ test("a report that disappears mid-save takes the row with it, and the saved verdict shows when it returns", async () => {
1676
+ const save: Deferred<ApiResponse> = createDeferred<ApiResponse>();
1677
+ postMock
1678
+ .mockResolvedValueOnce(
1679
+ completedResponse({
1680
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1681
+ }) as never,
1682
+ )
1683
+ .mockReturnValueOnce(save.promise as never)
1684
+ .mockResolvedValueOnce(noReportResponse() as never)
1685
+ .mockResolvedValueOnce(
1686
+ completedResponse({
1687
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1688
+ humanVerdict: AIRunHumanVerdict.Confirmed,
1689
+ }) as never,
1690
+ );
1691
+
1692
+ renderPanel();
1693
+ await flush();
1694
+ fireEvent.click(screen.getByRole("button", { name: "Confirmed" }));
1695
+ await flush();
1696
+
1697
+ expect(requestPath(1)).toContain("/ai-investigation/verdict");
1698
+ expect(screen.getByText(/You confirmed this analysis/)).toBeVisible();
1699
+
1700
+ await tick(SETTLED_POLL_INTERVAL_MS);
1701
+
1702
+ expect(postMock).toHaveBeenCalledTimes(3);
1703
+ expectNoRating();
1704
+ expect(actionsFrame()).toBeNull();
1705
+
1706
+ await resolveDeferred(save, successfulResponse({}));
1707
+
1708
+ expectNoRating();
1709
+ expect(screen.queryByRole("alert")).toBeNull();
1710
+
1711
+ await tick(SETTLED_POLL_INTERVAL_MS);
1712
+
1713
+ expect(postMock).toHaveBeenCalledTimes(4);
1714
+ expect(screen.getByText(/You confirmed this analysis/)).toBeVisible();
1715
+ expect(screen.queryByRole("alert")).toBeNull();
1716
+ });
1717
+
1718
+ test("a failed save's error leaves with the row when the report disappears", async () => {
1719
+ postMock
1720
+ .mockResolvedValueOnce(
1721
+ completedResponse({
1722
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1723
+ }) as never,
1724
+ )
1725
+ .mockResolvedValueOnce(
1726
+ new HTTPErrorResponse(
1727
+ 500,
1728
+ { message: "Verdict storage is unavailable." },
1729
+ {},
1730
+ ) as never,
1731
+ )
1732
+ .mockResolvedValueOnce(noReportResponse() as never);
1733
+
1734
+ renderPanel();
1735
+ await flush();
1736
+ fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
1737
+ await flush();
1738
+
1739
+ expect(screen.getByRole("alert")).toHaveTextContent(
1740
+ "Could not save your verdict",
1741
+ );
1742
+
1743
+ await tick(SETTLED_POLL_INTERVAL_MS);
1744
+
1745
+ expect(postMock).toHaveBeenCalledTimes(3);
1746
+ expectNoRating();
1747
+ expect(screen.queryByRole("alert")).toBeNull();
1748
+ expect(screen.queryByText(/Verdict storage is unavailable/)).toBeNull();
1749
+ });
1750
+
1751
+ test("drops the previous subject's rating when navigating to a subject without a report", async () => {
1752
+ postMock
1753
+ .mockResolvedValueOnce(
1754
+ completedResponse({
1755
+ humanVerdict: AIRunHumanVerdict.Confirmed,
1756
+ }) as never,
1757
+ )
1758
+ .mockResolvedValueOnce(noReportResponse({ runId: NEXT_RUN_ID }) as never);
1759
+
1760
+ const view: ReturnType<typeof render> = renderPanel();
1761
+ await flush();
1762
+ expect(screen.getByText(/You confirmed this analysis/)).toBeVisible();
1763
+
1764
+ view.rerender(
1765
+ <InvestigationPanel subjectType="alert" subjectId={ALERT_ID} />,
1766
+ );
1767
+ await flush();
1768
+
1769
+ expect(requestPath(1)).toContain("/ai-investigation/alert");
1770
+ expect(
1771
+ screen.getByText("No investigation report was published."),
1772
+ ).toBeVisible();
1773
+ expectNoRating();
1774
+ expect(actionsFrame()).toBeNull();
1775
+ });
1776
+
1777
+ test("a new run on the same subject hides the rating until its own report lands, then asks afresh", async () => {
1778
+ postMock
1779
+ .mockResolvedValueOnce(
1780
+ completedResponse({
1781
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1782
+ humanVerdict: AIRunHumanVerdict.Confirmed,
1783
+ }) as never,
1784
+ )
1785
+ .mockResolvedValueOnce(
1786
+ completedResponse({
1787
+ runId: NEXT_RUN_ID,
1788
+ analysisMarkdown: null,
1789
+ isAnalysisPending: true,
1790
+ codeFixRecommendation: AIRunCodeFixRecommendation.Pending,
1791
+ }) as never,
1792
+ )
1793
+ .mockResolvedValueOnce(
1794
+ completedResponse({
1795
+ runId: NEXT_RUN_ID,
1796
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1797
+ }) as never,
1798
+ );
1799
+
1800
+ renderPanel();
1801
+ await flush();
1802
+ expect(screen.getByText(/You confirmed this analysis/)).toBeVisible();
1803
+
1804
+ await tick(SETTLED_POLL_INTERVAL_MS);
1805
+
1806
+ expect(screen.getByText("Preparing the final report")).toBeVisible();
1807
+ expectNoRating();
1808
+ expect(actionsFrame()).toBeNull();
1809
+
1810
+ await tick(POLL_INTERVAL_MS);
1811
+
1812
+ expect(postMock).toHaveBeenCalledTimes(3);
1813
+ expectRatingOffered();
1814
+ // The previous run's verdict is not carried onto the new report.
1815
+ expect(screen.queryByText(/You confirmed this analysis/)).toBeNull();
1816
+ });
1817
+
1818
+ /*
1819
+ * The invariant behind the fix, across every completed-run shape: the
1820
+ * row is either absent or offers two working answers. It never sits on
1821
+ * the card with both disabled.
1822
+ */
1823
+ test.each([
1824
+ {
1825
+ label: "a report",
1826
+ response: (): ApiResponse => {
1827
+ return completedResponse();
1828
+ },
1829
+ offersRating: true,
1830
+ },
1831
+ {
1832
+ label: "a report with no fix recommended",
1833
+ response: (): ApiResponse => {
1834
+ return completedResponse({
1835
+ codeFixRecommendation: AIRunCodeFixRecommendation.NotRecommended,
1836
+ });
1837
+ },
1838
+ offersRating: true,
1839
+ },
1840
+ {
1841
+ label: "a report whose recommendation is still pending",
1842
+ response: (): ApiResponse => {
1843
+ return completedResponse({
1844
+ codeFixRecommendation: AIRunCodeFixRecommendation.Pending,
1845
+ });
1846
+ },
1847
+ offersRating: true,
1848
+ },
1849
+ {
1850
+ label: "a report with a TL;DR and structured evidence",
1851
+ response: (): ApiResponse => {
1852
+ return completedResponse({
1853
+ analysisTldr: TLDR,
1854
+ evidence: [],
1855
+ references: [],
1856
+ });
1857
+ },
1858
+ offersRating: true,
1859
+ },
1860
+ {
1861
+ label: "a report being prepared",
1862
+ response: (): ApiResponse => {
1863
+ return completedResponse({
1864
+ analysisMarkdown: null,
1865
+ isAnalysisPending: true,
1866
+ });
1867
+ },
1868
+ offersRating: false,
1869
+ },
1870
+ {
1871
+ label: "a report being prepared with a stored verdict",
1872
+ response: (): ApiResponse => {
1873
+ return completedResponse({
1874
+ analysisMarkdown: null,
1875
+ isAnalysisPending: true,
1876
+ humanVerdict: AIRunHumanVerdict.Rejected,
1877
+ });
1878
+ },
1879
+ offersRating: false,
1880
+ },
1881
+ {
1882
+ label: "no report and a Recommended fix",
1883
+ response: (): ApiResponse => {
1884
+ return completedResponse({ analysisMarkdown: null });
1885
+ },
1886
+ offersRating: false,
1887
+ },
1888
+ {
1889
+ label: "no report and no fix",
1890
+ response: (): ApiResponse => {
1891
+ return noReportResponse();
1892
+ },
1893
+ offersRating: false,
1894
+ },
1895
+ {
1896
+ label: "no report and no recorded steps",
1897
+ response: (): ApiResponse => {
1898
+ return noReportResponse({
1899
+ events: [],
1900
+ toolCallCount: 0,
1901
+ totalTokens: 0,
1902
+ });
1903
+ },
1904
+ offersRating: false,
1905
+ },
1906
+ {
1907
+ label: "a whitespace-only report",
1908
+ response: (): ApiResponse => {
1909
+ return noReportResponse({ analysisMarkdown: " \n " });
1910
+ },
1911
+ offersRating: false,
1912
+ },
1913
+ {
1914
+ label: "an API replica that predates report publication",
1915
+ response: (): ApiResponse => {
1916
+ return legacyCompletedResponse();
1917
+ },
1918
+ offersRating: false,
1919
+ },
1920
+ ])(
1921
+ "for $label the rating is offered=$offersRating and never disabled at rest",
1922
+ async (scenario: {
1923
+ label: string;
1924
+ response: () => ApiResponse;
1925
+ offersRating: boolean;
1926
+ }) => {
1927
+ postMock.mockResolvedValue(scenario.response() as never);
1928
+
1929
+ renderPanel();
1930
+ await flush();
1931
+
1932
+ expect(ratingHeading() !== null).toBe(scenario.offersRating);
1933
+ expect(ratingGroup() !== null).toBe(scenario.offersRating);
1934
+ expect(disabledVerdictAnswers()).toEqual([]);
1935
+ /*
1936
+ * The frame is drawn exactly when it holds a row: the rating, the
1937
+ * fix action, or both.
1938
+ */
1939
+ expect(actionsFrame() !== null).toBe(
1940
+ scenario.offersRating || fixButton() !== null,
1941
+ );
1942
+ },
1943
+ );
1944
+
1945
+ test("the answers are disabled only while a save is in flight", async () => {
1946
+ const save: Deferred<ApiResponse> = createDeferred<ApiResponse>();
1947
+ postMock
1948
+ .mockResolvedValueOnce(completedResponse() as never)
1949
+ .mockReturnValueOnce(save.promise as never);
1950
+
1951
+ renderPanel();
1952
+ await flush();
1953
+ expect(disabledVerdictAnswers()).toEqual([]);
1954
+
1955
+ fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
1956
+ await flush();
1957
+ fireEvent.click(screen.getByRole("button", { name: "Change" }));
1958
+
1959
+ expect(disabledVerdictAnswers()).toEqual(["Confirmed", "Rejected"]);
1960
+
1961
+ await resolveDeferred(save, successfulResponse({}));
1962
+
1963
+ expect(disabledVerdictAnswers()).toEqual([]);
1964
+ expectRatingOffered();
1965
+ });
1966
+ });
1967
+
1377
1968
  describe("InvestigationPanel code-fix recommendation", () => {
1378
1969
  test("shows the fix action only for an explicit Recommended decision", async () => {
1379
1970
  postMock.mockResolvedValue(completedResponse() as never);