@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
@@ -162,12 +162,31 @@ export class Service extends DatabaseService<Model> {
162
162
  this.assertCallerMayCreatePins(createBy.props);
163
163
 
164
164
  if (!isInternalCaller(createBy.props)) {
165
- /* The database keeps these for itself; a request does not set them. */
166
- delete createBy.data._id;
167
- delete createBy.data.createdAt;
168
- delete createBy.data.updatedAt;
169
- delete createBy.data.deletedAt;
170
- delete createBy.data.version;
165
+ /*
166
+ * The database keeps these for itself; a request does not set them.
167
+ *
168
+ * Cleared rather than deleted: `createBy.data` is a live model instance,
169
+ * and the column-metadata lookups downstream used to enumerate the own
170
+ * keys of whichever instance reached them first and cache that as the
171
+ * CLASS's column list - so deleting `_id` off this instance taught the
172
+ * whole process that RumSessionPin has no id, and every later response
173
+ * for it lost one. TableColumn.ts no longer reads the caller's instance
174
+ * (see CanonicalModelInstance.ts), so this is defence in depth. An
175
+ * unset column holds `undefined` anyway, which TypeORM and the write
176
+ * path treat exactly as an absent key - the save is still an INSERT.
177
+ */
178
+ const databaseManagedColumns: Array<string> = [
179
+ "_id",
180
+ "createdAt",
181
+ "updatedAt",
182
+ "deletedAt",
183
+ "version",
184
+ ];
185
+
186
+ for (const columnName of databaseManagedColumns) {
187
+ (createBy.data as unknown as Record<string, unknown>)[columnName] =
188
+ undefined;
189
+ }
171
190
  }
172
191
 
173
192
  const pinKey: PinKey | null = this.resolvePinKey(createBy);
@@ -0,0 +1,385 @@
1
+ import Label from "../../Models/DatabaseModels/Label";
2
+ import ServiceLevelObjective from "../../Models/DatabaseModels/ServiceLevelObjective";
3
+ import { ServiceLevelObjectiveFeedEventType } from "../../Models/DatabaseModels/ServiceLevelObjectiveFeed";
4
+ import ServiceLevelObjectiveLabelRule from "../../Models/DatabaseModels/ServiceLevelObjectiveLabelRule";
5
+ import { Purple500 } from "../../Types/BrandColors";
6
+ import ObjectID from "../../Types/ObjectID";
7
+ import { escapeMarkdownInline } from "../../Utils/Markdown/MarkdownEscape";
8
+ import { MAX_RULES_EVALUATED_PER_PROJECT } from "../../Utils/Rules/RuleEngineLimits";
9
+ import { RuleCriteriaMatcher } from "../../Utils/Rules/RuleCriteriaMatcher";
10
+ import RulePatternMatchUtil from "../../Utils/Rules/RulePatternMatchUtil";
11
+ import Select from "../Types/Database/Select";
12
+ import logger, { LogAttributes } from "../Utils/Logger";
13
+ import logIfRuleReadWasTruncated from "../Utils/Rules/RuleEngineRuleRead";
14
+ import {
15
+ ApplyRulesToExistingResourceData,
16
+ RuleApplicationResult,
17
+ RuleApplicationResultUtil,
18
+ RuleRunEngine,
19
+ } from "../Utils/Rules/RuleRun/RuleApplication";
20
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
21
+ import ServiceLevelObjectiveFeedService from "./ServiceLevelObjectiveFeedService";
22
+ import ServiceLevelObjectiveLabelRuleService from "./ServiceLevelObjectiveLabelRuleService";
23
+ import ServiceLevelObjectiveService from "./ServiceLevelObjectiveService";
24
+
25
+ class ServiceLevelObjectiveLabelRuleEngineServiceClass
26
+ implements
27
+ RuleRunEngine<ServiceLevelObjective, ServiceLevelObjectiveLabelRule>
28
+ {
29
+ public readonly ruleSelect: Select<ServiceLevelObjectiveLabelRule> = {
30
+ _id: true,
31
+ name: true,
32
+ criteria: true,
33
+ serviceLevelObjectiveLabels: { _id: true },
34
+ serviceLevelObjectiveNamePattern: true,
35
+ serviceLevelObjectiveDescriptionPattern: true,
36
+ labelsToAdd: { _id: true },
37
+ };
38
+
39
+ // Evaluation re-reads the SLO, so a run only has to name it.
40
+ public readonly resourceSelectForRuleRun: Select<ServiceLevelObjective> = {
41
+ _id: true,
42
+ projectId: true,
43
+ };
44
+
45
+ /**
46
+ * Evaluates ServiceLevelObjectiveLabelRule rows for the given SLO and
47
+ * attaches matched labels to it. The union is deduped against labels already
48
+ * on the SLO before insert to avoid PK conflicts on the join table.
49
+ */
50
+ @CaptureSpan()
51
+ public async applyRulesToServiceLevelObjective(
52
+ serviceLevelObjective: ServiceLevelObjective,
53
+ ): Promise<void> {
54
+ if (!serviceLevelObjective.id || !serviceLevelObjective.projectId) {
55
+ return;
56
+ }
57
+
58
+ try {
59
+ const rules: Array<ServiceLevelObjectiveLabelRule> =
60
+ await ServiceLevelObjectiveLabelRuleService.findBy({
61
+ query: {
62
+ projectId: serviceLevelObjective.projectId,
63
+ isEnabled: true,
64
+ },
65
+ props: { isRoot: true },
66
+ select: this.ruleSelect,
67
+ limit: MAX_RULES_EVALUATED_PER_PROJECT,
68
+ skip: 0,
69
+ });
70
+
71
+ logIfRuleReadWasTruncated({
72
+ ruleKind: "ServiceLevelObjectiveLabelRule",
73
+ projectId: serviceLevelObjective.projectId,
74
+ rulesRead: rules.length,
75
+ });
76
+
77
+ if (rules.length === 0) {
78
+ return;
79
+ }
80
+
81
+ await this.applyRules({
82
+ serviceLevelObjective: serviceLevelObjective,
83
+ rules: rules,
84
+ });
85
+ } catch (error) {
86
+ logger.error(`Error applying SLO label rules: ${error}`, {
87
+ projectId: serviceLevelObjective.projectId?.toString(),
88
+ serviceLevelObjectiveId: serviceLevelObjective.id?.toString(),
89
+ } as LogAttributes);
90
+ }
91
+ }
92
+
93
+ /*
94
+ * "Run now": the same evaluation, for an SLO that already exists and only
95
+ * the rules being run.
96
+ */
97
+ @CaptureSpan()
98
+ public async applyRulesToExistingResource(
99
+ data: ApplyRulesToExistingResourceData<
100
+ ServiceLevelObjective,
101
+ ServiceLevelObjectiveLabelRule
102
+ >,
103
+ ): Promise<RuleApplicationResult> {
104
+ try {
105
+ return await this.applyRules({
106
+ serviceLevelObjective: data.resource,
107
+ rules: data.rules,
108
+ });
109
+ } catch (error) {
110
+ logger.error(`Error running SLO label rules: ${error}`, {
111
+ projectId: data.resource.projectId?.toString(),
112
+ serviceLevelObjectiveId: data.resource.id?.toString(),
113
+ } as LogAttributes);
114
+
115
+ return RuleApplicationResultUtil.failed();
116
+ }
117
+ }
118
+
119
+ private async applyRules(data: {
120
+ serviceLevelObjective: ServiceLevelObjective;
121
+ rules: Array<ServiceLevelObjectiveLabelRule>;
122
+ }): Promise<RuleApplicationResult> {
123
+ const { serviceLevelObjective, rules } = data;
124
+
125
+ if (
126
+ !serviceLevelObjective.id ||
127
+ !serviceLevelObjective.projectId ||
128
+ rules.length === 0
129
+ ) {
130
+ return RuleApplicationResultUtil.noMatch();
131
+ }
132
+
133
+ const sloWithDetails: ServiceLevelObjective | null =
134
+ await ServiceLevelObjectiveService.findOneById({
135
+ id: serviceLevelObjective.id,
136
+ select: {
137
+ name: true,
138
+ description: true,
139
+ labels: { _id: true },
140
+ },
141
+ props: { isRoot: true },
142
+ });
143
+
144
+ if (!sloWithDetails) {
145
+ return RuleApplicationResultUtil.noMatch();
146
+ }
147
+
148
+ const labelIdsToAdd: Set<string> = new Set();
149
+ const matchedRuleNames: Array<string> = [];
150
+ let matchedAnyRule: boolean = false;
151
+
152
+ for (const rule of rules) {
153
+ if (!this.doesServiceLevelObjectiveMatchRule(sloWithDetails, rule)) {
154
+ continue;
155
+ }
156
+ matchedAnyRule = true;
157
+ if ((rule.labelsToAdd || []).length > 0) {
158
+ matchedRuleNames.push(
159
+ rule.name || rule.id?.toString() || "Unnamed rule",
160
+ );
161
+ }
162
+ for (const label of rule.labelsToAdd || []) {
163
+ if (label.id) {
164
+ labelIdsToAdd.add(label.id.toString());
165
+ }
166
+ }
167
+ }
168
+
169
+ if (!matchedAnyRule) {
170
+ return RuleApplicationResultUtil.noMatch();
171
+ }
172
+
173
+ if (labelIdsToAdd.size === 0) {
174
+ return RuleApplicationResultUtil.alreadyApplied();
175
+ }
176
+
177
+ const existingLabelIds: Set<string> = new Set(
178
+ (sloWithDetails.labels || [])
179
+ .map((l: Label) => {
180
+ return l.id?.toString() || "";
181
+ })
182
+ .filter((id: string) => {
183
+ return id !== "";
184
+ }),
185
+ );
186
+
187
+ const newLabelIds: Array<string> = Array.from(labelIdsToAdd).filter(
188
+ (id: string) => {
189
+ return !existingLabelIds.has(id);
190
+ },
191
+ );
192
+ if (newLabelIds.length === 0) {
193
+ return RuleApplicationResultUtil.alreadyApplied();
194
+ }
195
+
196
+ await ServiceLevelObjectiveService.getRepository()
197
+ .createQueryBuilder()
198
+ .relation(ServiceLevelObjective, "labels")
199
+ .of(serviceLevelObjective.id.toString())
200
+ .add(newLabelIds);
201
+
202
+ /*
203
+ * Sync in-memory labels so the owner-rule engine that runs next in the
204
+ * same onCreateSuccess chain can match on rule-added labels.
205
+ */
206
+ const mergedLabelIds: Set<string> = new Set([
207
+ ...existingLabelIds,
208
+ ...newLabelIds,
209
+ ]);
210
+ serviceLevelObjective.labels = Array.from(mergedLabelIds).map(
211
+ (id: string) => {
212
+ const label: Label = new Label();
213
+ label.id = new ObjectID(id);
214
+ return label;
215
+ },
216
+ );
217
+
218
+ logger.debug(
219
+ `ServiceLevelObjectiveLabelRuleEngine attached ${newLabelIds.length} labels to SLO ${serviceLevelObjective.id}`,
220
+ {
221
+ projectId: serviceLevelObjective.projectId.toString(),
222
+ } as LogAttributes,
223
+ );
224
+
225
+ await this.postLabelRuleFeedItem({
226
+ serviceLevelObjectiveId: serviceLevelObjective.id,
227
+ projectId: serviceLevelObjective.projectId,
228
+ sloName: sloWithDetails.name,
229
+ labelsAdded: newLabelIds.length,
230
+ matchedRuleNames: matchedRuleNames,
231
+ });
232
+
233
+ return RuleApplicationResultUtil.updated(newLabelIds.length);
234
+ }
235
+
236
+ /*
237
+ * Labels arriving from a rule rather than from a person is exactly what the
238
+ * SLO's feed cannot otherwise explain, so it records which rules did it.
239
+ * The labels are already attached by now: a feed failure is logged, never
240
+ * thrown, or a run would report an SLO it changed as one it failed on.
241
+ */
242
+ private async postLabelRuleFeedItem(data: {
243
+ serviceLevelObjectiveId: ObjectID;
244
+ projectId: ObjectID;
245
+ sloName: string | undefined;
246
+ labelsAdded: number;
247
+ matchedRuleNames: Array<string>;
248
+ }): Promise<void> {
249
+ try {
250
+ const sloLink: string =
251
+ await ServiceLevelObjectiveService.getSloMarkdownLink({
252
+ projectId: data.projectId,
253
+ sloId: data.serviceLevelObjectiveId,
254
+ sloName: data.sloName,
255
+ });
256
+
257
+ await ServiceLevelObjectiveFeedService.createServiceLevelObjectiveFeedItem(
258
+ {
259
+ serviceLevelObjectiveId: data.serviceLevelObjectiveId,
260
+ projectId: data.projectId,
261
+ serviceLevelObjectiveFeedEventType:
262
+ ServiceLevelObjectiveFeedEventType.LabelRuleExecuted,
263
+ displayColor: Purple500,
264
+ feedInfoInMarkdown: `🏷️ ${data.labelsAdded} label(s) were attached to ${sloLink} by label ${data.matchedRuleNames.length === 1 ? "rule" : "rules"}.`,
265
+ moreInformationInMarkdown: `**Label rules that matched**: ${data.matchedRuleNames
266
+ .map((name: string): string => {
267
+ // Rule names are user-controlled and the feed renders markdown.
268
+ return `**${escapeMarkdownInline(name)}**`;
269
+ })
270
+ .join(", ")}`,
271
+ },
272
+ );
273
+ } catch (error) {
274
+ logger.error(
275
+ `Error writing the label rule feed item for SLO ${data.serviceLevelObjectiveId.toString()}: ${error}`,
276
+ { projectId: data.projectId.toString() } as LogAttributes,
277
+ );
278
+ }
279
+ }
280
+
281
+ private doesServiceLevelObjectiveMatchRule(
282
+ serviceLevelObjective: ServiceLevelObjective,
283
+ rule: ServiceLevelObjectiveLabelRule,
284
+ ): boolean {
285
+ return RuleCriteriaMatcher.matchesWithLegacySync({
286
+ rule,
287
+ legacyFields: [
288
+ "serviceLevelObjectiveLabels",
289
+ "serviceLevelObjectiveNamePattern",
290
+ "serviceLevelObjectiveDescriptionPattern",
291
+ ],
292
+ emptyResult: true,
293
+ matchesLegacyRule: (
294
+ legacyRule: ServiceLevelObjectiveLabelRule,
295
+ ): boolean => {
296
+ return this.doesServiceLevelObjectiveMatchLegacyRule(
297
+ serviceLevelObjective,
298
+ legacyRule,
299
+ );
300
+ },
301
+ });
302
+ }
303
+
304
+ private doesServiceLevelObjectiveMatchLegacyRule(
305
+ serviceLevelObjective: ServiceLevelObjective,
306
+ rule: ServiceLevelObjectiveLabelRule,
307
+ ): boolean {
308
+ if (
309
+ rule.serviceLevelObjectiveLabels &&
310
+ rule.serviceLevelObjectiveLabels.length > 0
311
+ ) {
312
+ if (
313
+ !serviceLevelObjective.labels ||
314
+ serviceLevelObjective.labels.length === 0
315
+ ) {
316
+ return false;
317
+ }
318
+ const ruleLabelIds: Array<string> = rule.serviceLevelObjectiveLabels.map(
319
+ (l: Label) => {
320
+ return l.id?.toString() || "";
321
+ },
322
+ );
323
+ const labelIds: Array<string> = serviceLevelObjective.labels.map(
324
+ (l: Label) => {
325
+ return l.id?.toString() || "";
326
+ },
327
+ );
328
+ if (
329
+ !ruleLabelIds.some((id: string) => {
330
+ return labelIds.includes(id);
331
+ })
332
+ ) {
333
+ return false;
334
+ }
335
+ }
336
+
337
+ if (
338
+ rule.serviceLevelObjectiveNamePattern &&
339
+ (!serviceLevelObjective.name ||
340
+ !this.testPattern(
341
+ rule.serviceLevelObjectiveNamePattern,
342
+ serviceLevelObjective.name,
343
+ rule,
344
+ ))
345
+ ) {
346
+ return false;
347
+ }
348
+
349
+ if (
350
+ rule.serviceLevelObjectiveDescriptionPattern &&
351
+ (!serviceLevelObjective.description ||
352
+ !this.testPattern(
353
+ rule.serviceLevelObjectiveDescriptionPattern,
354
+ serviceLevelObjective.description,
355
+ rule,
356
+ ))
357
+ ) {
358
+ return false;
359
+ }
360
+
361
+ return true;
362
+ }
363
+
364
+ /*
365
+ * Patterns are regexes, with a '*' wildcard fallback - the same two syntaxes
366
+ * the SLO monitor rules take. SloRulePatternValidator rejects anything else
367
+ * on save, so this only warns about a rule written before that check.
368
+ */
369
+ private testPattern(
370
+ pattern: string,
371
+ value: string,
372
+ rule: ServiceLevelObjectiveLabelRule,
373
+ ): boolean {
374
+ if (!RulePatternMatchUtil.isSupportedPattern(pattern)) {
375
+ logger.warn(
376
+ `Invalid pattern in SLO label rule ${rule.id}: ${pattern}. It is neither a valid regular expression nor a wildcard pattern, so it will never match.`,
377
+ );
378
+ return false;
379
+ }
380
+
381
+ return RulePatternMatchUtil.matches(value, pattern);
382
+ }
383
+ }
384
+
385
+ export default new ServiceLevelObjectiveLabelRuleEngineServiceClass();
@@ -0,0 +1,51 @@
1
+ import DatabaseService from "./DatabaseService";
2
+ import Model from "../../Models/DatabaseModels/ServiceLevelObjectiveLabelRule";
3
+ import CreateBy from "../Types/Database/CreateBy";
4
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
5
+ import UpdateBy from "../Types/Database/UpdateBy";
6
+ import SloRulePatternValidator from "../Utils/Slo/SloRulePatternValidator";
7
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
8
+
9
+ /*
10
+ * No hard-delete retention: a rule is configuration, not an event log, so it
11
+ * stays until somebody deletes it.
12
+ */
13
+ export class Service extends DatabaseService<Model> {
14
+ public constructor() {
15
+ super(Model);
16
+ }
17
+
18
+ /*
19
+ * A pattern that is neither a valid regex nor a wildcard can only ever match
20
+ * nothing, and the rule engine has no way to say so - it just quietly stops
21
+ * labelling. Reject it while the user is still looking at the form.
22
+ */
23
+ @CaptureSpan()
24
+ protected override async onBeforeCreate(
25
+ createBy: CreateBy<Model>,
26
+ ): Promise<OnCreate<Model>> {
27
+ SloRulePatternValidator.validate({
28
+ namePattern: createBy.data.serviceLevelObjectiveNamePattern,
29
+ descriptionPattern: createBy.data.serviceLevelObjectiveDescriptionPattern,
30
+ });
31
+
32
+ return { createBy: createBy, carryForward: null };
33
+ }
34
+
35
+ @CaptureSpan()
36
+ protected override async onBeforeUpdate(
37
+ updateBy: UpdateBy<Model>,
38
+ ): Promise<OnUpdate<Model>> {
39
+ SloRulePatternValidator.validate({
40
+ namePattern: updateBy.data.serviceLevelObjectiveNamePattern as
41
+ | string
42
+ | undefined,
43
+ descriptionPattern: updateBy.data
44
+ .serviceLevelObjectiveDescriptionPattern as string | undefined,
45
+ });
46
+
47
+ return { updateBy: updateBy, carryForward: null };
48
+ }
49
+ }
50
+
51
+ export default new Service();
@@ -7,8 +7,19 @@ import { Gray500, Green500 } from "../../Types/BrandColors";
7
7
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
8
8
  import PartialEntity from "../../Types/Database/PartialEntity";
9
9
  import ObjectID from "../../Types/ObjectID";
10
+ import FilterCondition from "../../Types/Filter/FilterCondition";
11
+ import RuleCriteria, {
12
+ RuleCriteriaFilter,
13
+ RuleCriteriaOperator,
14
+ } from "../../Types/Rules/RuleCriteria";
15
+ import {
16
+ getMonitorTypeCriteriaValidationError,
17
+ isMonitorTypeCriteriaValue,
18
+ } from "../../Utils/Rules/MonitorTypeRuleCriteria";
10
19
  import { escapeMarkdownInline } from "../../Utils/Markdown/MarkdownEscape";
11
- import RuleCriteriaMatcher from "../../Utils/Rules/RuleCriteriaMatcher";
20
+ import RuleCriteriaMatcher, {
21
+ isValidRuleCriteria,
22
+ } from "../../Utils/Rules/RuleCriteriaMatcher";
12
23
  import { MAX_RULES_EVALUATED_PER_PROJECT } from "../../Utils/Rules/RuleEngineLimits";
13
24
  import RulePatternMatchUtil from "../../Utils/Rules/RulePatternMatchUtil";
14
25
  import QueryHelper from "../Types/Database/QueryHelper";
@@ -96,6 +107,7 @@ const RULE_SELECT: Select<ServiceLevelObjectiveMonitorRule> = {
96
107
  serviceLevelObjectiveId: true,
97
108
  isEnabled: true,
98
109
  monitorLabels: { _id: true },
110
+ monitorType: true,
99
111
  monitorNamePattern: true,
100
112
  monitorDescriptionPattern: true,
101
113
  criteria: true,
@@ -122,7 +134,7 @@ const MAX_MONITORS_LISTED_IN_FEED_DETAILS: number = 50;
122
134
  *
123
135
  * - the SLO side (one of its rules was created, edited, disabled or
124
136
  * deleted) -> syncMonitorsForSlo
125
- * - the monitor side (its labels, name or description changed, or it was
137
+ * - the monitor side (its labels, type, name or description changed, or it was
126
138
  * just created) -> syncSlosForMonitor
127
139
  *
128
140
  * Both write through ServiceLevelObjective.autoAddedMonitors, which records
@@ -215,6 +227,7 @@ export class ServiceLevelObjectiveMonitorRuleEngineServiceClass {
215
227
  projectId: true,
216
228
  name: true,
217
229
  description: true,
230
+ monitorType: true,
218
231
  labels: {
219
232
  _id: true,
220
233
  },
@@ -479,20 +492,64 @@ export class ServiceLevelObjectiveMonitorRuleEngineServiceClass {
479
492
  monitor: Monitor;
480
493
  rule: ServiceLevelObjectiveMonitorRule;
481
494
  }): boolean {
482
- return RuleCriteriaMatcher.matchesWithLegacySync({
483
- rule: data.rule,
484
- legacyFields: [
485
- "monitorLabels",
486
- "monitorNamePattern",
487
- "monitorDescriptionPattern",
488
- ],
495
+ const criteria: RuleCriteria | null | undefined = data.rule.criteria;
496
+
497
+ if (criteria === undefined || criteria === null) {
498
+ return this.doesMonitorMatchLegacyRule(data);
499
+ }
500
+
501
+ // A malformed type condition must fail the whole rule, even under Match any.
502
+ if (
503
+ !isValidRuleCriteria(criteria) ||
504
+ criteria.filters.some((filter: RuleCriteriaFilter): boolean => {
505
+ return (
506
+ filter.field === "monitorType" &&
507
+ getMonitorTypeCriteriaValidationError(filter) !== null
508
+ );
509
+ })
510
+ ) {
511
+ return false;
512
+ }
513
+
514
+ return RuleCriteriaMatcher.matchesSync({
515
+ criteria: criteria,
489
516
  emptyResult: false,
490
- matchesLegacyRule: (
491
- legacyRule: ServiceLevelObjectiveMonitorRule,
492
- ): boolean => {
493
- return this.doesMonitorMatchLegacyRule({
494
- monitor: data.monitor,
495
- rule: legacyRule,
517
+ matchesFilter: (filter: RuleCriteriaFilter): boolean => {
518
+ if (filter.field === "monitorType") {
519
+ if (!isMonitorTypeCriteriaValue(data.monitor.monitorType)) {
520
+ return false;
521
+ }
522
+
523
+ return filter.operator === RuleCriteriaOperator.Equals
524
+ ? data.monitor.monitorType === filter.value
525
+ : data.monitor.monitorType !== filter.value;
526
+ }
527
+
528
+ // Existing text and label conditions retain their legacy-compatible semantics.
529
+ return RuleCriteriaMatcher.matchesWithLegacySync({
530
+ rule: {
531
+ ...data.rule,
532
+ criteria: {
533
+ ...criteria,
534
+ filterCondition: FilterCondition.All,
535
+ filters: [filter],
536
+ },
537
+ } as ServiceLevelObjectiveMonitorRule,
538
+ legacyFields: [
539
+ "monitorLabels",
540
+ "monitorType",
541
+ "monitorNamePattern",
542
+ "monitorDescriptionPattern",
543
+ ],
544
+ emptyResult: false,
545
+ matchesLegacyRule: (
546
+ legacyRule: ServiceLevelObjectiveMonitorRule,
547
+ ): boolean => {
548
+ return this.doesMonitorMatchLegacyRule({
549
+ monitor: data.monitor,
550
+ rule: legacyRule,
551
+ });
552
+ },
496
553
  });
497
554
  },
498
555
  });
@@ -512,7 +569,24 @@ export class ServiceLevelObjectiveMonitorRuleEngineServiceClass {
512
569
  rule.monitorDescriptionPattern,
513
570
  );
514
571
 
515
- if (!hasLabelCriteria && !hasNameCriteria && !hasDescriptionCriteria) {
572
+ const hasTypeCriteria: boolean =
573
+ rule.monitorType !== undefined && rule.monitorType !== null;
574
+
575
+ if (
576
+ !hasLabelCriteria &&
577
+ !hasNameCriteria &&
578
+ !hasDescriptionCriteria &&
579
+ !hasTypeCriteria
580
+ ) {
581
+ return false;
582
+ }
583
+
584
+ if (
585
+ hasTypeCriteria &&
586
+ (!isMonitorTypeCriteriaValue(rule.monitorType) ||
587
+ !isMonitorTypeCriteriaValue(monitor.monitorType) ||
588
+ monitor.monitorType !== rule.monitorType)
589
+ ) {
516
590
  return false;
517
591
  }
518
592
 
@@ -638,6 +712,7 @@ export class ServiceLevelObjectiveMonitorRuleEngineServiceClass {
638
712
  _id: true,
639
713
  name: true,
640
714
  description: true,
715
+ monitorType: true,
641
716
  labels: {
642
717
  _id: true,
643
718
  },
@@ -663,6 +738,7 @@ export class ServiceLevelObjectiveMonitorRuleEngineServiceClass {
663
738
 
664
739
  return Boolean(
665
740
  (rule.monitorLabels && rule.monitorLabels.length > 0) ||
741
+ rule.monitorType ||
666
742
  rule.monitorNamePattern ||
667
743
  rule.monitorDescriptionPattern,
668
744
  );