@oneuptime/common 13.0.5 → 13.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1091) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +81 -1
  2. package/Models/AnalyticsModels/SecurityEvent.ts +4 -4
  3. package/Models/DatabaseModels/Alert.ts +62 -0
  4. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  5. package/Models/DatabaseModels/Incident.ts +66 -0
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +74 -0
  7. package/Models/DatabaseModels/IncidentPublicNote.ts +74 -0
  8. package/Models/DatabaseModels/Index.ts +6 -4
  9. package/Models/DatabaseModels/NetworkDevice.ts +67 -0
  10. package/Models/DatabaseModels/NetworkDeviceDiagnostic.ts +746 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +151 -0
  12. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +1 -1
  13. package/Models/DatabaseModels/Project.ts +41 -0
  14. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +74 -0
  15. package/Models/DatabaseModels/SecurityEventConnection.ts +11 -11
  16. package/Models/DatabaseModels/ServiceLevelObjective.ts +185 -8
  17. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +746 -43
  18. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +575 -0
  19. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +582 -0
  20. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +16 -0
  21. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +16 -0
  22. package/Models/DatabaseModels/StatusPageAnnouncement.ts +75 -0
  23. package/Models/DatabaseModels/ThreatIntelFeed.ts +1 -1
  24. package/Server/API/BaseAPI.ts +17 -0
  25. package/Server/API/BillingInvoiceAPI.ts +343 -30
  26. package/Server/API/BillingPaymentMethodAPI.ts +126 -5
  27. package/Server/API/DashboardAPI.ts +96 -2
  28. package/Server/API/SecurityEventConnectionAPI.ts +141 -11
  29. package/Server/API/StatusPageAPI.ts +308 -199
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.ts +83 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.ts +36 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.ts +29 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.ts +516 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.ts +98 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.ts +27 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.ts +97 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  38. package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +138 -67
  39. package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +213 -84
  40. package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +112 -35
  41. package/Server/Services/AlertLabelRuleEngineService.ts +299 -217
  42. package/Server/Services/AlertOwnerRuleEngineService.ts +572 -396
  43. package/Server/Services/AlertPrivacyRuleEngineService.ts +116 -40
  44. package/Server/Services/AlertService.ts +111 -4
  45. package/Server/Services/AuditLogService.ts +612 -59
  46. package/Server/Services/BillingInvoiceService.ts +112 -102
  47. package/Server/Services/BillingService.ts +539 -11
  48. package/Server/Services/CephClusterLabelRuleEngineService.ts +170 -109
  49. package/Server/Services/CephClusterOwnerRuleEngineService.ts +233 -115
  50. package/Server/Services/CloudResourceLabelRuleEngineService.ts +163 -100
  51. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +236 -115
  52. package/Server/Services/DashboardLabelRuleEngineService.ts +145 -84
  53. package/Server/Services/DashboardOwnerRuleEngineService.ts +213 -95
  54. package/Server/Services/DatabaseService.ts +171 -21
  55. package/Server/Services/DockerHostLabelRuleEngineService.ts +171 -110
  56. package/Server/Services/DockerHostOwnerRuleEngineService.ts +233 -115
  57. package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +181 -112
  58. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +243 -118
  59. package/Server/Services/HostLabelRuleEngineService.ts +167 -106
  60. package/Server/Services/HostOwnerRuleEngineService.ts +229 -111
  61. package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +141 -67
  62. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +272 -72
  63. package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +112 -35
  64. package/Server/Services/IncidentEpisodePublicNoteService.ts +24 -0
  65. package/Server/Services/IncidentLabelRuleEngineService.ts +279 -204
  66. package/Server/Services/IncidentOwnerRuleEngineService.ts +595 -425
  67. package/Server/Services/IncidentPrivacyRuleEngineService.ts +117 -44
  68. package/Server/Services/IncidentPublicNoteService.ts +24 -0
  69. package/Server/Services/IncidentService.ts +114 -3
  70. package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +147 -83
  71. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +221 -100
  72. package/Server/Services/Index.ts +6 -4
  73. package/Server/Services/IoTFleetLabelRuleEngineService.ts +145 -84
  74. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +213 -95
  75. package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +181 -112
  76. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +243 -118
  77. package/Server/Services/LabelService.ts +23 -28
  78. package/Server/Services/MonitorLabelRuleEngineService.ts +152 -92
  79. package/Server/Services/MonitorOwnerRuleEngineService.ts +220 -104
  80. package/Server/Services/MonitorProbeService.ts +20 -2
  81. package/Server/Services/MonitorService.ts +11 -9
  82. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +376 -5
  83. package/Server/Services/NetworkDeviceDiagnosticService.ts +417 -0
  84. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +147 -83
  85. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +218 -97
  86. package/Server/Services/NetworkDeviceService.ts +39 -2
  87. package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +151 -80
  88. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +222 -97
  89. package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +154 -83
  90. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +225 -100
  91. package/Server/Services/PodmanHostLabelRuleEngineService.ts +171 -110
  92. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +235 -115
  93. package/Server/Services/ProjectService.ts +111 -10
  94. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +174 -110
  95. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +239 -116
  96. package/Server/Services/RumApplicationLabelRuleEngineService.ts +137 -73
  97. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +200 -83
  98. package/Server/Services/RunbookLabelRuleEngineService.ts +146 -84
  99. package/Server/Services/RunbookOwnerRuleEngineService.ts +216 -95
  100. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +324 -230
  101. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +613 -428
  102. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +24 -0
  103. package/Server/Services/ScheduledMaintenanceService.ts +43 -14
  104. package/Server/Services/SecurityEventConnectionService.ts +56 -4
  105. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +143 -74
  106. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +206 -85
  107. package/Server/Services/ServiceLabelRuleEngineService.ts +172 -110
  108. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +1057 -18
  109. package/Server/Services/ServiceLevelObjectiveFeedService.ts +108 -0
  110. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +793 -97
  111. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +1069 -0
  112. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +240 -1
  113. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +257 -1
  114. package/Server/Services/ServiceLevelObjectiveService.ts +1356 -56
  115. package/Server/Services/ServiceOwnerRuleEngineService.ts +238 -116
  116. package/Server/Services/StatusPageAnnouncementService.ts +13 -0
  117. package/Server/Services/StatusPageLabelRuleEngineService.ts +146 -85
  118. package/Server/Services/StatusPageOwnerRuleEngineService.ts +210 -99
  119. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +28 -232
  120. package/Server/Services/StatusPageSubscriberService.ts +6 -0
  121. package/Server/Services/TelemetryUsageBillingService.ts +38 -7
  122. package/Server/Services/ThreatIntelFeedService.ts +1 -1
  123. package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +173 -110
  124. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +238 -116
  125. package/Server/Services/WorkflowLabelRuleEngineService.ts +145 -84
  126. package/Server/Services/WorkflowOwnerRuleEngineService.ts +215 -95
  127. package/Server/Types/Database/UpdateByID.ts +3 -0
  128. package/Server/Types/Database/UpdateOneBy.ts +7 -0
  129. package/Server/Utils/AI/AlertAIContextBuilder.ts +19 -0
  130. package/Server/Utils/AI/IncidentAIContextBuilder.ts +39 -0
  131. package/Server/Utils/AI/Toolbox/AlertTools.ts +37 -1
  132. package/Server/Utils/AI/Toolbox/IncidentTools.ts +22 -1
  133. package/Server/Utils/AI/Toolbox/SloTools.ts +416 -51
  134. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +151 -13
  135. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +17 -4
  136. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +155 -8
  137. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +16 -0
  138. package/Server/Utils/Database/RelationValueUtil.ts +106 -0
  139. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +6 -1
  140. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +22 -27
  141. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +3 -1
  142. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +50 -20
  143. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +13 -1
  144. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +6 -11
  145. package/Server/Utils/Rules/MonitorRulePatternValidator.ts +51 -0
  146. package/Server/Utils/Rules/OwnerRuleAssignment.ts +110 -0
  147. package/Server/Utils/Rules/RuleRun/RuleApplication.ts +81 -0
  148. package/Server/Utils/Rules/RuleRun/RuleRunPermission.ts +188 -0
  149. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +803 -0
  150. package/Server/Utils/Rules/RuleRun/RuleRunner.ts +341 -0
  151. package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +3 -2
  152. package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +6 -4
  153. package/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.ts +263 -16
  154. package/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.ts +2101 -0
  155. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +194 -14
  156. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.ts +1 -2
  157. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +38 -7
  158. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +2 -0
  159. package/Server/Utils/SecurityEvent/Connectors/Types.ts +242 -2
  160. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +1 -1
  161. package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +3 -3
  162. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +2 -2
  163. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +217 -56
  164. package/Server/Utils/Slo/SloFeedUtil.ts +200 -0
  165. package/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.ts +173 -0
  166. package/Server/Utils/Slo/SloMetricUtil.ts +327 -0
  167. package/Server/Utils/Slo/SloOwnerReferenceValidator.ts +208 -0
  168. package/Server/Utils/Slo/SloRecordReferenceValidator.ts +169 -0
  169. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +6 -43
  170. package/Server/Utils/StatusPageResource.ts +50 -5
  171. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +664 -15
  172. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +4 -1
  173. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +307 -0
  174. package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +289 -0
  175. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +598 -0
  176. package/Tests/App/Dashboard/BillingDefaultPaymentMethod.test.tsx +1046 -0
  177. package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +3 -0
  178. package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +201 -7
  179. package/Tests/App/Dashboard/BooleanSeriesCriteriaFilterText.test.ts +82 -0
  180. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +16 -1
  181. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +116 -8
  182. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +168 -1
  183. package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +1 -1
  184. package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +20 -3
  185. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +1095 -1
  186. package/Tests/App/Dashboard/CorrelateFilterChips.test.tsx +910 -0
  187. package/Tests/App/Dashboard/CorrelateGraph.test.tsx +3747 -25
  188. package/Tests/App/Dashboard/CorrelateGraphHelpers.test.ts +1085 -0
  189. package/Tests/App/Dashboard/CorrelateInspector.test.tsx +1534 -0
  190. package/Tests/App/Dashboard/CorrelateNodeCard.test.tsx +965 -0
  191. package/Tests/App/Dashboard/CorrelateResultSummary.test.tsx +1525 -0
  192. package/Tests/App/Dashboard/CorrelationGraph.test.ts +1030 -0
  193. package/Tests/App/Dashboard/CorrelationGraphLayout.test.ts +526 -0
  194. package/Tests/App/Dashboard/DeviceDiagnostics.test.tsx +787 -0
  195. package/Tests/App/Dashboard/DeviceLatencyTrend.test.tsx +278 -0
  196. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +279 -0
  197. package/Tests/App/Dashboard/DiscoveryScanEditForm.test.tsx +87 -0
  198. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +443 -8
  199. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +340 -0
  200. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +98 -2
  201. package/Tests/App/Dashboard/ExceptionSegmentedControl.test.tsx +1020 -0
  202. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +268 -47
  203. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1114 -76
  204. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +124 -2
  205. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +279 -176
  206. package/Tests/App/Dashboard/InvestigationRunDetails.test.tsx +1166 -0
  207. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +437 -0
  208. package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +65 -0
  209. package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +5 -0
  210. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +74 -0
  211. package/Tests/App/Dashboard/ResourceFeed.test.tsx +125 -5
  212. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  213. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +1764 -0
  214. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1000 -64
  215. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +448 -0
  216. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +739 -189
  217. package/Tests/App/Dashboard/SecurityEventSeverityPill.test.tsx +233 -0
  218. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +282 -0
  219. package/Tests/App/Dashboard/SloActiveBurnEventsCard.test.tsx +538 -0
  220. package/Tests/App/Dashboard/SloBulkActionsArchive.test.tsx +252 -0
  221. package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +322 -518
  222. package/Tests/App/Dashboard/SloElement.test.tsx +194 -0
  223. package/Tests/App/Dashboard/SloFeed.test.tsx +289 -0
  224. package/Tests/App/Dashboard/SloHistoryCharts.test.tsx +471 -0
  225. package/Tests/App/Dashboard/SloHistorySeries.test.tsx +607 -0
  226. package/Tests/App/Dashboard/SloListWidget.test.tsx +783 -0
  227. package/Tests/App/Dashboard/SloMetricsPage.test.tsx +346 -0
  228. package/Tests/App/Dashboard/SloMonitorsPage.test.tsx +661 -0
  229. package/Tests/App/Dashboard/SloMonitorsSummaryCard.test.tsx +489 -0
  230. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +437 -0
  231. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +305 -0
  232. package/Tests/App/Dashboard/SloOverviewData.test.tsx +563 -0
  233. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +311 -0
  234. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +426 -0
  235. package/Tests/App/Dashboard/SloOverviewSidebarCards.test.tsx +493 -0
  236. package/Tests/App/Dashboard/SloSettings.test.tsx +633 -0
  237. package/Tests/App/Dashboard/SloStatusSummaryCards.test.tsx +403 -0
  238. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +373 -0
  239. package/Tests/App/Dashboard/SloWidgetVariableBinding.test.tsx +689 -0
  240. package/Tests/App/Dashboard/TopologyConnectivitySection.test.tsx +206 -0
  241. package/Tests/App/Dashboard/TracesEntityNames.test.tsx +47 -15
  242. package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +1312 -0
  243. package/Tests/App/Dashboard/WidgetCatalog.test.ts +9 -1
  244. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +14 -16
  245. package/Tests/Models/DatabaseModels/AuditLogModelConfiguration.test.ts +442 -0
  246. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +9 -10
  247. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +48 -1
  248. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +835 -0
  249. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +3 -2
  250. package/Tests/Models/DiscoveryScanNetbiosLookupColumn.test.ts +328 -0
  251. package/Tests/Models/DiscoveryScanShortDeviceNamesColumn.test.ts +335 -0
  252. package/Tests/Models/NetworkDeviceDiagnosticContract.test.ts +194 -0
  253. package/Tests/Models/NetworkDeviceDnsNameColumn.test.ts +321 -0
  254. package/Tests/Models/ProjectDataResidencyColumn.test.ts +154 -0
  255. package/Tests/Models/SecurityDomainAccessControl.test.ts +181 -50
  256. package/Tests/Server/API/BaseAPI.test.ts +6 -0
  257. package/Tests/Server/API/BaseAPIUpdateMiscDataProps.test.ts +217 -0
  258. package/Tests/Server/API/BillingInvoiceAPI.test.ts +7 -0
  259. package/Tests/Server/API/BillingInvoiceAPIPaymentStates.test.ts +990 -0
  260. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +498 -0
  261. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +405 -0
  262. package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +901 -7
  263. package/Tests/Server/API/SessionReplayAPI.test.ts +116 -0
  264. package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +857 -0
  265. package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +1084 -0
  266. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +33 -3
  267. package/Tests/Server/Infrastructure/Postgres/AddDataResidencyToProjectMigration.test.ts +202 -0
  268. package/Tests/Server/Infrastructure/Postgres/AddNetbiosLookupToNetworkDeviceDiscoveryScanMigration.test.ts +330 -0
  269. package/Tests/Server/Infrastructure/Postgres/AddNetworkDeviceDnsNameAndShortDeviceNamesMigration.test.ts +340 -0
  270. package/Tests/Server/Infrastructure/Postgres/BackfillSloMonitorRulesAndAffectedResourcesMigration.test.ts +343 -0
  271. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +801 -0
  272. package/Tests/Server/Services/AddSubscriberUpdateNotificationStatusMigration.test.ts +307 -0
  273. package/Tests/Server/Services/AuditLogService.test.ts +1124 -0
  274. package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +200 -1
  275. package/Tests/Server/Services/BillingInvoiceServiceMutexRelease.test.ts +254 -0
  276. package/Tests/Server/Services/BillingService.test.ts +70 -0
  277. package/Tests/Server/Services/BillingServicePayInvoiceStates.test.ts +723 -0
  278. package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +14 -2
  279. package/Tests/Server/Services/BillingServiceSubscriptionPaymentMethodSync.test.ts +1634 -0
  280. package/Tests/Server/Services/DatabaseServiceAuditRelationDiff.test.ts +492 -0
  281. package/Tests/Server/Services/DatabaseServicePasswordFieldSecrets.test.ts +629 -0
  282. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +431 -0
  283. package/Tests/Server/Services/IncidentAlertSloReferenceGuard.test.ts +358 -0
  284. package/Tests/Server/Services/MonitorProbeServicePastDueMonitoring.test.ts +362 -0
  285. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1460 -1
  286. package/Tests/Server/Services/NetworkDeviceDiagnosticService.test.ts +962 -0
  287. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +106 -0
  288. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +10 -1
  289. package/Tests/Server/Services/NetworkDeviceServicePastDueMonitoring.test.ts +335 -0
  290. package/Tests/Server/Services/NetworkDeviceSiteRuleDnsName.test.ts +568 -0
  291. package/Tests/Server/Services/ProjectDataResidencyPostgres.test.ts +344 -0
  292. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +187 -0
  293. package/Tests/Server/Services/ProjectServiceDataResidency.test.ts +369 -0
  294. package/Tests/Server/Services/ProjectServiceDataResidencySelfHosted.test.ts +176 -0
  295. package/Tests/Server/Services/ProjectServicePastDueMonitoring.test.ts +289 -0
  296. package/Tests/Server/Services/ResourceFeedServices.test.ts +24 -8
  297. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +1396 -0
  298. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupARun.test.ts +917 -0
  299. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +1262 -0
  300. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +902 -0
  301. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +1163 -0
  302. package/Tests/Server/Services/RuleRun/PrivacyRuleEnginesRun.test.ts +843 -0
  303. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +465 -0
  304. package/Tests/Server/Services/SecurityEventConnectionService.test.ts +525 -4
  305. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +77 -23
  306. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleFeedWrites.test.ts +777 -0
  307. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleOptions.test.ts +1399 -0
  308. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +67 -74
  309. package/Tests/Server/Services/ServiceLevelObjectiveChildRowTenancy.test.ts +906 -0
  310. package/Tests/Server/Services/ServiceLevelObjectiveDeleteTenancy.test.ts +1029 -0
  311. package/Tests/Server/Services/ServiceLevelObjectiveFeedService.test.ts +313 -0
  312. package/Tests/Server/Services/ServiceLevelObjectiveFeedWrites.test.ts +1214 -0
  313. package/Tests/Server/Services/ServiceLevelObjectiveMarkdownLink.test.ts +289 -0
  314. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +1455 -430
  315. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleLegacyLabelAdoption.test.ts +634 -0
  316. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +1193 -0
  317. package/Tests/Server/Services/{SloMonitorLabelRuleHooks.test.ts → ServiceLevelObjectiveMonitorRuleTriggers.test.ts} +135 -41
  318. package/Tests/Server/Services/ServiceLevelObjectiveOwnerFeedWrites.test.ts +671 -0
  319. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +180 -85
  320. package/Tests/Server/Services/ServiceLevelObjectiveServiceArchive.test.ts +537 -0
  321. package/Tests/Server/Services/ServiceLevelObjectiveServiceLegacyMonitorLabelWrite.test.ts +870 -0
  322. package/Tests/Server/Services/ServiceLevelObjectiveServiceMonitorRuleGuard.test.ts +343 -0
  323. package/Tests/Server/Services/ServiceLevelObjectiveServiceReEvaluation.test.ts +246 -0
  324. package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +501 -0
  325. package/Tests/Server/Services/SloAffectedResourceLinkContract.test.ts +86 -0
  326. package/Tests/Server/Services/SloAffectedResourceMetricAttributes.test.ts +547 -0
  327. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +10 -4
  328. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +7 -2
  329. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +174 -0
  330. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateServiceVariables.test.ts +40 -0
  331. package/Tests/Server/Services/SubscriberUpdateNotificationHooks.test.ts +541 -0
  332. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +288 -0
  333. package/Tests/Server/TestingUtils/PastDueMonitoringClaimSql.ts +177 -0
  334. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +51 -10
  335. package/Tests/Server/TestingUtils/__mocks__/Stripe.mock.ts +16 -1
  336. package/Tests/Server/Types/Database/Permissions/ProjectDataResidencyColumn.test.ts +386 -0
  337. package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +26 -36
  338. package/Tests/Server/Utils/AI/SloAffectedResourceAIContext.test.ts +445 -0
  339. package/Tests/Server/Utils/AI/SloTools.test.ts +423 -1
  340. package/Tests/Server/Utils/AI/SloToolsArchive.test.ts +294 -0
  341. package/Tests/Server/Utils/AI/SloToolsRuleReadPermissions.test.ts +297 -0
  342. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +255 -10
  343. package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +404 -750
  344. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +45 -0
  345. package/Tests/Server/Utils/Database/RelationValueUtil.test.ts +157 -0
  346. package/Tests/Server/Utils/Monitor/Criteria/BooleanSeriesEvaluateOverTime.test.ts +260 -0
  347. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +181 -0
  348. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +147 -30
  349. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.test.ts +17 -0
  350. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +136 -0
  351. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidatorLoadOrder.test.ts +472 -0
  352. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +48 -2
  353. package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +435 -475
  354. package/Tests/Server/Utils/Rules/MonitorRulePatternValidator.test.ts +77 -0
  355. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +177 -0
  356. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +365 -0
  357. package/Tests/Server/Utils/Rules/RuleRun/RuleRunRegistry.test.ts +173 -0
  358. package/Tests/Server/Utils/Rules/RuleRun/RuleRunner.test.ts +675 -0
  359. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +8 -8
  360. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorFetchSummary.test.ts +261 -0
  361. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +68 -13
  362. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsAuth.test.ts → Connectors/GoogleSecOps/GoogleSecOpsAuth.test.ts} +5 -5
  363. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClient.test.ts → Connectors/GoogleSecOps/GoogleSecOpsClient.test.ts} +4 -4
  364. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.test.ts +483 -0
  365. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorCuratedAndLateAlerts.test.ts +676 -0
  366. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFetchEvents.test.ts +1994 -0
  367. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFixtures.ts +332 -0
  368. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorHttpIntegration.test.ts +680 -0
  369. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorRequestContract.test.ts +1206 -0
  370. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorTestConnection.test.ts +1136 -0
  371. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsCuratedRuleCounts.test.ts +407 -0
  372. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsErrorHandling.test.ts → Connectors/GoogleSecOps/GoogleSecOpsErrorHandling.test.ts} +5 -5
  373. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingAdaptiveCatchUp.test.ts +730 -0
  374. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClickhouseIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingClickhouseIntegration.test.ts} +130 -35
  375. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFailureTaxonomy.test.ts +772 -0
  376. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFixtures.ts +648 -0
  377. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsHttpIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingHttpIntegration.test.ts} +230 -225
  378. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingIntegration.test.ts +1390 -0
  379. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingLoop.test.ts +981 -0
  380. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingNothingImportedRegression.test.ts +290 -0
  381. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsRequestContract.test.ts → Connectors/GoogleSecOps/GoogleSecOpsRequestContract.test.ts} +2 -2
  382. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsResponseParsing.test.ts → Connectors/GoogleSecOps/GoogleSecOpsResponseParsing.test.ts} +5 -5
  383. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsSearchDetections.test.ts → Connectors/GoogleSecOps/GoogleSecOpsSearchDetections.test.ts} +38 -5
  384. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsTesterIntegration.test.ts +421 -0
  385. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +1445 -3
  386. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +14 -4
  387. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +313 -4
  388. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +352 -0
  389. package/Tests/Server/Utils/Slo/SloFeedUtil.test.ts +326 -0
  390. package/Tests/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.test.ts +260 -0
  391. package/Tests/Server/Utils/Slo/SloMetricUtil.test.ts +592 -0
  392. package/Tests/Server/Utils/Slo/SloRecordReferenceValidator.test.ts +311 -0
  393. package/Tests/Server/Utils/StatusPageResource.test.ts +91 -3
  394. package/Tests/Types/Billing/SubscriptionStatus.test.ts +176 -0
  395. package/Tests/Types/Billing/SubscriptionStatusPastDueMonitoring.test.ts +187 -0
  396. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +53 -7
  397. package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +816 -792
  398. package/Tests/Types/Monitor/CriteriaFilter.test.ts +216 -24
  399. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +14 -1
  400. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +14 -1
  401. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +14 -1
  402. package/Tests/Types/Monitor/MonitorStepRetriesParsing.test.ts +201 -0
  403. package/Tests/Types/Rules/RuleRun.test.ts +315 -0
  404. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +60 -0
  405. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +29 -4
  406. package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +217 -0
  407. package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +200 -0
  408. package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +141 -87
  409. package/Tests/UI/Components/AlertBanner.test.tsx +319 -0
  410. package/Tests/UI/Components/BulkArchiveActionsCopy.test.tsx +310 -0
  411. package/Tests/UI/Components/Detail/DetailIdIsUnique.test.tsx +87 -0
  412. package/Tests/UI/Components/Dropdown/DropdownClearable.test.tsx +393 -0
  413. package/Tests/UI/Components/Dropdown/DropdownMultiSelectChipAccessibleName.test.tsx +64 -0
  414. package/Tests/UI/Components/EmptyState/EmptyState.test.tsx +335 -4
  415. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +337 -0
  416. package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +21 -20
  417. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +15 -2
  418. package/Tests/UI/Components/LockedFilterChip.test.tsx +281 -144
  419. package/Tests/UI/Components/MoreMenu.test.tsx +133 -0
  420. package/Tests/UI/Components/MoreMenuMotion.test.tsx +84 -3
  421. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  422. package/Tests/UI/Components/RuleRun/RuleDetailFields.test.tsx +336 -0
  423. package/Tests/UI/Components/RuleRun/RuleTable.test.tsx +304 -0
  424. package/Tests/UI/Components/RuleRun/RunRuleNowModal.test.tsx +231 -0
  425. package/Tests/UI/Components/RuleRun/RunRulesBulkAction.test.ts +213 -0
  426. package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +124 -61
  427. package/Tests/UI/Rum/ReplayEngine.test.ts +154 -0
  428. package/Tests/UI/Rum/ReplayHeader.test.tsx +234 -123
  429. package/Tests/UI/Rum/ReplayPinControl.test.tsx +122 -0
  430. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +245 -0
  431. package/Tests/UI/Rum/ReplayRail.test.tsx +294 -0
  432. package/Tests/UI/Rum/ReplayScrubber.test.tsx +213 -1
  433. package/Tests/UI/Rum/ReplayStage.test.tsx +565 -172
  434. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +260 -3
  435. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +1391 -0
  436. package/Tests/UI/Rum/ReplayTimeline.test.tsx +222 -0
  437. package/Tests/UI/Utils/DashboardStackingLayers.test.ts +8 -1
  438. package/Tests/UI/Utils/RuleRunClient.test.ts +303 -0
  439. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +1 -0
  440. package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +2 -0
  441. package/Tests/Utils/Dashboard/Components/DashboardSloListComponent.test.ts +206 -0
  442. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +36 -2
  443. package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +409 -588
  444. package/Tests/Utils/Dashboard/SloWidgetSource.test.ts +351 -0
  445. package/Tests/Utils/Markdown/MarkdownEscape.test.ts +361 -0
  446. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +1425 -118
  447. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +188 -3
  448. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +661 -13
  449. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +349 -0
  450. package/Tests/Utils/NetworkDiscovery/RunImportedDeviceNaming.test.ts +656 -0
  451. package/Tests/Utils/NetworkDiscovery/ShortDeviceNamePlanner.test.ts +1020 -0
  452. package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +619 -0
  453. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +317 -0
  454. package/Tests/Utils/Project/DataResidency.test.ts +198 -0
  455. package/Tests/Utils/Rules/RuleRunSummary.test.ts +394 -0
  456. package/Tests/Utils/Slo/SloAffectedResourceMarkdown.test.ts +302 -0
  457. package/Tests/Utils/Slo/SloBurnRateTemplate.test.ts +468 -0
  458. package/Tests/Utils/Slo/SloEvaluation.test.ts +20 -4
  459. package/Tests/Utils/Slo/SloFeedMarkdown.test.ts +1185 -0
  460. package/Tests/Utils/Slo/SloHealth.test.ts +262 -0
  461. package/Tests/Utils/Slo/SloHistoryMetricName.test.ts +102 -0
  462. package/Tests/Utils/Slo/SloListWidgetFormat.test.ts +522 -0
  463. package/Tests/Utils/Slo/SloMetricType.test.ts +355 -0
  464. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +387 -0
  465. package/Tests/Utils/Slo/SloMonitorStatusSummary.test.ts +210 -0
  466. package/Tests/Utils/Slo/SloOverviewText.test.ts +226 -0
  467. package/Tests/Utils/Slo/SloProjection.test.ts +1039 -0
  468. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +47 -0
  469. package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +1 -80
  470. package/Types/BaseDatabase/EnableAuditLogOn.ts +41 -0
  471. package/Types/Billing/SubscriptionStatus.ts +39 -4
  472. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  473. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +5 -0
  474. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +10 -0
  475. package/Types/Dashboard/DashboardComponents/DashboardSloListComponent.ts +29 -0
  476. package/Types/Dashboard/DashboardTemplates.ts +290 -297
  477. package/Types/Database/EnableAuditLog.ts +23 -1
  478. package/Types/Email/EmailTemplateType.ts +4 -0
  479. package/Types/Monitor/CriteriaFilter.ts +55 -8
  480. package/Types/Monitor/MonitorStep.ts +5 -2
  481. package/Types/Monitor/MonitorStepDnsMonitor.ts +3 -1
  482. package/Types/Monitor/MonitorStepDnssecMonitor.ts +3 -1
  483. package/Types/Monitor/MonitorStepDomainMonitor.ts +3 -1
  484. package/Types/Monitor/MonitorStepExternalStatusPageMonitor.ts +3 -1
  485. package/Types/Monitor/MonitorStepRetries.ts +59 -0
  486. package/Types/Monitor/MonitorStepSnmpMonitor.ts +9 -2
  487. package/Types/NetworkDevice/NetworkDeviceDiagnosticResult.ts +104 -0
  488. package/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.ts +47 -0
  489. package/Types/NetworkDevice/NetworkDeviceDiagnosticType.ts +47 -0
  490. package/Types/NetworkDevice/NetworkDevicePingMetricNames.ts +20 -0
  491. package/Types/Permission.ts +127 -0
  492. package/Types/Rules/RuleCriteriaFieldRegistry.ts +5 -0
  493. package/Types/Rules/RuleRun.ts +518 -0
  494. package/Types/Rum/SessionReplayApi.ts +18 -0
  495. package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +6 -0
  496. package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +30 -4
  497. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +108 -1
  498. package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +6 -2
  499. package/Types/ServiceLevelObjective/SloHistoryMetricName.ts +25 -0
  500. package/Types/ServiceLevelObjective/SloMetricType.ts +49 -0
  501. package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +4 -0
  502. package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +331 -0
  503. package/Types/StatusPage/SubscriberNotificationTrigger.ts +12 -0
  504. package/Types/StatusPage/SubscriberUpdateNotification.ts +89 -0
  505. package/Types/Telemetry/LockedFilterDetail.ts +7 -28
  506. package/Types/Telemetry/ServiceType.ts +7 -0
  507. package/Typings/Index.d.ts +53 -3
  508. package/UI/Components/AlertBanner/AlertBanner.tsx +85 -27
  509. package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +21 -2
  510. package/UI/Components/Detail/Detail.tsx +9 -2
  511. package/UI/Components/Dropdown/Dropdown.tsx +64 -1
  512. package/UI/Components/EmptyState/EmptyState.tsx +27 -3
  513. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +124 -0
  514. package/UI/Components/Forms/ModelForm.tsx +6 -5
  515. package/UI/Components/LabelRule/LabelRuleTable.tsx +8 -2
  516. package/UI/Components/LogsViewer/LogsViewer.tsx +2 -6
  517. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +2 -13
  518. package/UI/Components/LogsViewer/types.ts +2 -2
  519. package/UI/Components/MoreMenu/MoreMenu.tsx +14 -3
  520. package/UI/Components/RuleRun/RuleDetailFields.tsx +359 -0
  521. package/UI/Components/RuleRun/RuleTable.tsx +183 -0
  522. package/UI/Components/RuleRun/RuleView.tsx +170 -0
  523. package/UI/Components/RuleRun/RunRuleNowModal.tsx +147 -0
  524. package/UI/Components/RuleRun/RunRulesBulkAction.ts +103 -0
  525. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +2 -6
  526. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +38 -104
  527. package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +2 -18
  528. package/UI/Components/TelemetryViewer/types.ts +2 -2
  529. package/UI/Utils/Rules/RuleRunClient.ts +178 -0
  530. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +8 -0
  531. package/Utils/Dashboard/Components/DashboardSloComponent.ts +19 -2
  532. package/Utils/Dashboard/Components/DashboardSloListComponent.ts +126 -0
  533. package/Utils/Dashboard/Components/Index.ts +7 -0
  534. package/Utils/Dashboard/SloWidgetSource.ts +188 -0
  535. package/Utils/Markdown/MarkdownEscape.ts +63 -0
  536. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +161 -36
  537. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +25 -0
  538. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +146 -0
  539. package/Utils/NetworkDiscovery/RunImportedDeviceNaming.ts +390 -0
  540. package/Utils/NetworkDiscovery/ShortDeviceNamePlanner.ts +291 -0
  541. package/Utils/NetworkDiscovery/ShortHostnameUtil.ts +91 -0
  542. package/Utils/NetworkSite/CidrMatchUtil.ts +37 -12
  543. package/Utils/Project/DataResidency.ts +63 -0
  544. package/Utils/Rules/RuleRunSummary.ts +323 -0
  545. package/Utils/Slo/SloAffectedResourceMarkdown.ts +123 -0
  546. package/Utils/Slo/SloBurnRateTemplate.ts +373 -0
  547. package/Utils/Slo/SloFeedMarkdown.ts +1507 -0
  548. package/Utils/Slo/SloHealth.ts +96 -9
  549. package/Utils/Slo/SloListWidgetFormat.ts +370 -0
  550. package/Utils/Slo/SloMetricType.ts +237 -0
  551. package/Utils/Slo/SloMonitorRuleCriteria.ts +364 -0
  552. package/Utils/Slo/SloMonitorStatusSummary.ts +210 -0
  553. package/Utils/Slo/SloOverviewText.ts +265 -0
  554. package/Utils/Slo/SloProjection.ts +967 -0
  555. package/Utils/Slo/SloWidgetFormat.ts +12 -2
  556. package/Utils/Telemetry/LockedFilterSearch.ts +3 -49
  557. package/build/dist/Models/AnalyticsModels/AuditLog.js +70 -1
  558. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  559. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +4 -4
  560. package/build/dist/Models/DatabaseModels/Alert.js +60 -0
  561. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  562. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  563. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  564. package/build/dist/Models/DatabaseModels/Incident.js +64 -0
  565. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  566. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +75 -0
  567. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  568. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +75 -0
  569. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  570. package/build/dist/Models/DatabaseModels/Index.js +6 -4
  571. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  572. package/build/dist/Models/DatabaseModels/NetworkDevice.js +68 -0
  573. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  574. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js +772 -0
  575. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js.map +1 -0
  576. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +140 -0
  577. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  578. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +1 -1
  579. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
  580. package/build/dist/Models/DatabaseModels/Project.js +42 -0
  581. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  582. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +75 -0
  583. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  584. package/build/dist/Models/DatabaseModels/SecurityEventConnection.js +11 -11
  585. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +192 -10
  586. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  587. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +798 -96
  588. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
  589. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +596 -0
  590. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -0
  591. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +590 -0
  592. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -0
  593. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +16 -0
  594. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -1
  595. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +16 -0
  596. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -1
  597. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +75 -0
  598. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  599. package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +1 -1
  600. package/build/dist/Server/API/BaseAPI.js +14 -0
  601. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  602. package/build/dist/Server/API/BillingInvoiceAPI.js +233 -19
  603. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  604. package/build/dist/Server/API/BillingPaymentMethodAPI.js +86 -5
  605. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  606. package/build/dist/Server/API/DashboardAPI.js +72 -2
  607. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  608. package/build/dist/Server/API/SecurityEventConnectionAPI.js +102 -10
  609. package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -1
  610. package/build/dist/Server/API/StatusPageAPI.js +236 -154
  611. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  612. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js +34 -0
  613. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js.map +1 -0
  614. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js +24 -0
  615. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js.map +1 -0
  616. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js +21 -0
  617. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js.map +1 -0
  618. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js +207 -0
  619. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js.map +1 -0
  620. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js +72 -0
  621. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js.map +1 -0
  622. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js +20 -0
  623. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js.map +1 -0
  624. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js +46 -0
  625. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js.map +1 -0
  626. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  627. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  628. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +112 -56
  629. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
  630. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +167 -68
  631. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
  632. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +87 -26
  633. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
  634. package/build/dist/Server/Services/AlertLabelRuleEngineService.js +270 -203
  635. package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
  636. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +498 -354
  637. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
  638. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +97 -34
  639. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
  640. package/build/dist/Server/Services/AlertService.js +91 -8
  641. package/build/dist/Server/Services/AlertService.js.map +1 -1
  642. package/build/dist/Server/Services/AuditLogService.js +408 -44
  643. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  644. package/build/dist/Server/Services/BillingInvoiceService.js +94 -85
  645. package/build/dist/Server/Services/BillingInvoiceService.js.map +1 -1
  646. package/build/dist/Server/Services/BillingService.js +406 -14
  647. package/build/dist/Server/Services/BillingService.js.map +1 -1
  648. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +141 -92
  649. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
  650. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +189 -101
  651. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  652. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +135 -86
  653. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  654. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +189 -100
  655. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  656. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +117 -69
  657. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
  658. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +171 -83
  659. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  660. package/build/dist/Server/Services/DatabaseService.js +125 -18
  661. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  662. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +141 -92
  663. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
  664. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +189 -101
  665. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  666. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +145 -91
  667. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
  668. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +191 -101
  669. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  670. package/build/dist/Server/Services/HostLabelRuleEngineService.js +141 -92
  671. package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
  672. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +190 -102
  673. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  674. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +112 -56
  675. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
  676. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +220 -63
  677. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  678. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +87 -26
  679. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
  680. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
  681. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  682. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +258 -192
  683. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
  684. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +519 -376
  685. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
  686. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +95 -32
  687. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
  688. package/build/dist/Server/Services/IncidentPublicNoteService.js +24 -0
  689. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  690. package/build/dist/Server/Services/IncidentService.js +90 -5
  691. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  692. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +113 -65
  693. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
  694. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +171 -83
  695. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  696. package/build/dist/Server/Services/Index.js +6 -4
  697. package/build/dist/Server/Services/Index.js.map +1 -1
  698. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +117 -69
  699. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
  700. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +171 -83
  701. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  702. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +145 -91
  703. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
  704. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +191 -101
  705. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  706. package/build/dist/Server/Services/LabelService.js +20 -25
  707. package/build/dist/Server/Services/LabelService.js.map +1 -1
  708. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +123 -77
  709. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
  710. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +167 -82
  711. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
  712. package/build/dist/Server/Services/MonitorProbeService.js +18 -2
  713. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  714. package/build/dist/Server/Services/MonitorService.js +11 -9
  715. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  716. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +287 -5
  717. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  718. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js +333 -0
  719. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js.map +1 -0
  720. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +117 -69
  721. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  722. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +171 -83
  723. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  724. package/build/dist/Server/Services/NetworkDeviceService.js +36 -2
  725. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  726. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +117 -64
  727. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
  728. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +173 -83
  729. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  730. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +116 -65
  731. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
  732. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +171 -83
  733. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  734. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +141 -92
  735. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
  736. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +189 -101
  737. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  738. package/build/dist/Server/Services/ProjectService.js +82 -10
  739. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  740. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +141 -92
  741. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
  742. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +189 -101
  743. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  744. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +111 -63
  745. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  746. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +161 -77
  747. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  748. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +117 -69
  749. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
  750. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +171 -83
  751. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  752. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +280 -209
  753. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
  754. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +521 -376
  755. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
  756. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +24 -0
  757. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  758. package/build/dist/Server/Services/ScheduledMaintenanceService.js +24 -8
  759. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  760. package/build/dist/Server/Services/SecurityEventConnectionService.js +43 -3
  761. package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -1
  762. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +115 -62
  763. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  764. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +163 -77
  765. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  766. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +141 -92
  767. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
  768. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +769 -18
  769. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
  770. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js +96 -0
  771. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js.map +1 -0
  772. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +614 -87
  773. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  774. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +844 -0
  775. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -0
  776. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +207 -1
  777. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -1
  778. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +221 -1
  779. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -1
  780. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +997 -50
  781. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  782. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +191 -102
  783. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  784. package/build/dist/Server/Services/StatusPageAnnouncementService.js +12 -0
  785. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  786. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +118 -70
  787. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
  788. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +158 -76
  789. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
  790. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +19 -215
  791. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  792. package/build/dist/Server/Services/StatusPageSubscriberService.js +6 -0
  793. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  794. package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -5
  795. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  796. package/build/dist/Server/Services/ThreatIntelFeedService.js +1 -1
  797. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +141 -92
  798. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
  799. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +189 -101
  800. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
  801. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +117 -69
  802. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
  803. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +171 -83
  804. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  805. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +17 -0
  806. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  807. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +31 -0
  808. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  809. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +24 -1
  810. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  811. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +21 -1
  812. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  813. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +337 -53
  814. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  815. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +108 -15
  816. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  817. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +2 -2
  818. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -1
  819. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +115 -6
  820. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -1
  821. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +13 -0
  822. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  823. package/build/dist/Server/Utils/Database/RelationValueUtil.js +82 -0
  824. package/build/dist/Server/Utils/Database/RelationValueUtil.js.map +1 -0
  825. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +10 -6
  826. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  827. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +17 -21
  828. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  829. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +5 -4
  830. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  831. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +50 -10
  832. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  833. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +13 -1
  834. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  835. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +6 -10
  836. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  837. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js +34 -0
  838. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js.map +1 -0
  839. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +69 -0
  840. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -0
  841. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js +25 -0
  842. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js.map +1 -0
  843. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js +128 -0
  844. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js.map +1 -0
  845. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +746 -0
  846. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -0
  847. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js +221 -0
  848. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js.map +1 -0
  849. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +3 -2
  850. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
  851. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +6 -4
  852. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -1
  853. package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.js +174 -14
  854. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
  855. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js +1417 -0
  856. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js.map +1 -0
  857. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +138 -18
  858. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -1
  859. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js +1 -2
  860. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -1
  861. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +23 -18
  862. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -1
  863. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +2 -0
  864. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -1
  865. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +95 -0
  866. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -1
  867. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +1 -1
  868. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +3 -3
  869. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +2 -2
  870. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +118 -40
  871. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  872. package/build/dist/Server/Utils/Slo/SloFeedUtil.js +150 -0
  873. package/build/dist/Server/Utils/Slo/SloFeedUtil.js.map +1 -0
  874. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js +136 -0
  875. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js.map +1 -0
  876. package/build/dist/Server/Utils/Slo/SloMetricUtil.js +269 -0
  877. package/build/dist/Server/Utils/Slo/SloMetricUtil.js.map +1 -0
  878. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js +134 -0
  879. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js.map +1 -0
  880. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js +137 -0
  881. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js.map +1 -0
  882. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +6 -26
  883. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -1
  884. package/build/dist/Server/Utils/StatusPageResource.js +31 -5
  885. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
  886. package/build/dist/Types/Billing/SubscriptionStatus.js +37 -3
  887. package/build/dist/Types/Billing/SubscriptionStatus.js.map +1 -1
  888. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  889. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  890. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +5 -0
  891. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  892. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js +2 -0
  893. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js.map +1 -0
  894. package/build/dist/Types/Dashboard/DashboardTemplates.js +275 -286
  895. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  896. package/build/dist/Types/Database/EnableAuditLog.js +19 -1
  897. package/build/dist/Types/Database/EnableAuditLog.js.map +1 -1
  898. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  899. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  900. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -6
  901. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  902. package/build/dist/Types/Monitor/MonitorStep.js +2 -0
  903. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  904. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js +3 -1
  905. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js.map +1 -1
  906. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js +3 -1
  907. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js.map +1 -1
  908. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +3 -1
  909. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  910. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js +3 -1
  911. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js.map +1 -1
  912. package/build/dist/Types/Monitor/MonitorStepRetries.js +47 -0
  913. package/build/dist/Types/Monitor/MonitorStepRetries.js.map +1 -0
  914. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -1
  915. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
  916. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js +29 -0
  917. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js.map +1 -0
  918. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js +37 -0
  919. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js.map +1 -0
  920. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js +42 -0
  921. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js.map +1 -0
  922. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js +20 -0
  923. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js.map +1 -0
  924. package/build/dist/Types/Permission.js +114 -0
  925. package/build/dist/Types/Permission.js.map +1 -1
  926. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +5 -0
  927. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  928. package/build/dist/Types/Rules/RuleRun.js +267 -0
  929. package/build/dist/Types/Rules/RuleRun.js.map +1 -0
  930. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  931. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -1
  932. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +16 -1
  933. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -1
  934. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +65 -0
  935. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
  936. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +6 -2
  937. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -1
  938. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js +26 -0
  939. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js.map +1 -0
  940. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js +45 -0
  941. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js.map +1 -0
  942. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
  943. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
  944. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +295 -0
  945. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -0
  946. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js +13 -0
  947. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js.map +1 -0
  948. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +67 -0
  949. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -0
  950. package/build/dist/Types/Telemetry/LockedFilterDetail.js +7 -7
  951. package/build/dist/Types/Telemetry/ServiceType.js +7 -0
  952. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  953. package/build/dist/UI/Components/AlertBanner/AlertBanner.js +48 -19
  954. package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -1
  955. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +10 -2
  956. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
  957. package/build/dist/UI/Components/Detail/Detail.js +12 -3
  958. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  959. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -5
  960. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  961. package/build/dist/UI/Components/EmptyState/EmptyState.js +3 -3
  962. package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
  963. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +47 -0
  964. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +1 -0
  965. package/build/dist/UI/Components/Forms/ModelForm.js +6 -5
  966. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  967. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +6 -2
  968. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -1
  969. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +1 -1
  970. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  971. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +0 -2
  972. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  973. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +3 -1
  974. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  975. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js +226 -0
  976. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js.map +1 -0
  977. package/build/dist/UI/Components/RuleRun/RuleTable.js +97 -0
  978. package/build/dist/UI/Components/RuleRun/RuleTable.js.map +1 -0
  979. package/build/dist/UI/Components/RuleRun/RuleView.js +83 -0
  980. package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -0
  981. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js +74 -0
  982. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js.map +1 -0
  983. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js +78 -0
  984. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js.map +1 -0
  985. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
  986. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  987. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +24 -50
  988. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
  989. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +0 -4
  990. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
  991. package/build/dist/UI/Utils/Rules/RuleRunClient.js +98 -0
  992. package/build/dist/UI/Utils/Rules/RuleRunClient.js.map +1 -0
  993. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +8 -0
  994. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  995. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +16 -2
  996. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -1
  997. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js +94 -0
  998. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js.map +1 -0
  999. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  1000. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  1001. package/build/dist/Utils/Dashboard/SloWidgetSource.js +125 -0
  1002. package/build/dist/Utils/Dashboard/SloWidgetSource.js.map +1 -0
  1003. package/build/dist/Utils/Markdown/MarkdownEscape.js +49 -0
  1004. package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -0
  1005. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +112 -34
  1006. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  1007. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +22 -0
  1008. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  1009. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +129 -0
  1010. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -0
  1011. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js +255 -0
  1012. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js.map +1 -0
  1013. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js +184 -0
  1014. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js.map +1 -0
  1015. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js +79 -0
  1016. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js.map +1 -0
  1017. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +21 -12
  1018. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
  1019. package/build/dist/Utils/Project/DataResidency.js +51 -0
  1020. package/build/dist/Utils/Project/DataResidency.js.map +1 -0
  1021. package/build/dist/Utils/Rules/RuleRunSummary.js +197 -0
  1022. package/build/dist/Utils/Rules/RuleRunSummary.js.map +1 -0
  1023. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js +51 -0
  1024. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js.map +1 -0
  1025. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +228 -0
  1026. package/build/dist/Utils/Slo/SloBurnRateTemplate.js.map +1 -0
  1027. package/build/dist/Utils/Slo/SloFeedMarkdown.js +934 -0
  1028. package/build/dist/Utils/Slo/SloFeedMarkdown.js.map +1 -0
  1029. package/build/dist/Utils/Slo/SloHealth.js +75 -9
  1030. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  1031. package/build/dist/Utils/Slo/SloListWidgetFormat.js +217 -0
  1032. package/build/dist/Utils/Slo/SloListWidgetFormat.js.map +1 -0
  1033. package/build/dist/Utils/Slo/SloMetricType.js +212 -0
  1034. package/build/dist/Utils/Slo/SloMetricType.js.map +1 -0
  1035. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +216 -0
  1036. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -0
  1037. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js +129 -0
  1038. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js.map +1 -0
  1039. package/build/dist/Utils/Slo/SloOverviewText.js +110 -0
  1040. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -0
  1041. package/build/dist/Utils/Slo/SloProjection.js +448 -0
  1042. package/build/dist/Utils/Slo/SloProjection.js.map +1 -0
  1043. package/build/dist/Utils/Slo/SloWidgetFormat.js +4 -2
  1044. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -1
  1045. package/build/dist/Utils/Telemetry/LockedFilterSearch.js +1 -26
  1046. package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -1
  1047. package/package.json +1 -1
  1048. package/Models/DatabaseModels/GoogleSecOpsConnection.ts +0 -447
  1049. package/Models/DatabaseModels/GoogleSecOpsConnectionRun.ts +0 -263
  1050. package/Server/API/GoogleSecOpsConnectionAPI.ts +0 -320
  1051. package/Server/Services/GoogleSecOpsConnectionRunService.ts +0 -10
  1052. package/Server/Services/GoogleSecOpsConnectionService.ts +0 -116
  1053. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.ts +0 -777
  1054. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +0 -1373
  1055. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +0 -512
  1056. package/Tests/App/Dashboard/GoogleSecOpsConnectionForm.test.tsx +0 -838
  1057. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +0 -441
  1058. package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +0 -1001
  1059. package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +0 -657
  1060. package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +0 -153
  1061. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.test.ts +0 -784
  1062. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +0 -823
  1063. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +0 -918
  1064. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +0 -738
  1065. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +0 -874
  1066. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +0 -1297
  1067. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsThreePassPoller.test.ts +0 -1577
  1068. package/Tests/UI/Components/LockedFilterActions.test.tsx +0 -396
  1069. package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +0 -111
  1070. package/UI/Components/TelemetryViewer/components/LockedFilterActions.tsx +0 -205
  1071. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +0 -478
  1072. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +0 -1
  1073. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js +0 -287
  1074. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +0 -1
  1075. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +0 -231
  1076. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +0 -1
  1077. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js +0 -9
  1078. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +0 -1
  1079. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +0 -70
  1080. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +0 -1
  1081. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +0 -1
  1082. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js +0 -537
  1083. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js.map +0 -1
  1084. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +0 -1034
  1085. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +0 -1
  1086. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +0 -410
  1087. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +0 -1
  1088. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +0 -2
  1089. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +0 -1
  1090. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js +0 -88
  1091. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js.map +0 -1
@@ -0,0 +1,1390 @@
1
+ import SecurityEventConnection from "../../../../../../Models/DatabaseModels/SecurityEventConnection";
2
+ import Semaphore from "../../../../../../Server/Infrastructure/Semaphore";
3
+ import OTelIngestService from "../../../../../../Server/Services/OpenTelemetryIngestService";
4
+ import SecurityEventService from "../../../../../../Server/Services/SecurityEventService";
5
+ import { Statement } from "../../../../../../Server/Utils/AnalyticsDatabase/Statement";
6
+ import SecurityEventConnectionPoller from "../../../../../../Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller";
7
+ import SecurityEventConnectorRegistry from "../../../../../../Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry";
8
+ import SecurityEventDedupe from "../../../../../../Server/Utils/SecurityEvent/SecurityEventDedupe";
9
+ import ThreatIntelEnricher, {
10
+ EnrichmentResult,
11
+ } from "../../../../../../Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelEnricher";
12
+ import OneUptimeDate from "../../../../../../Types/Date";
13
+ import { JSONObject } from "../../../../../../Types/JSON";
14
+ import ObjectID from "../../../../../../Types/ObjectID";
15
+ import {
16
+ LEGACY_GOOGLE_SECOPS_CONNECTION_ID_ATTRIBUTE,
17
+ SECURITY_CONNECTION_ID_ATTRIBUTE,
18
+ SecurityEventConnectionRunResult,
19
+ } from "../../../../../../Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics";
20
+ import NormalizedSecurityEvent from "../../../../../../Types/SecurityEvent/NormalizedSecurityEvent";
21
+ import GoogleSecOpsAlertNormalizer from "../../../../../../Utils/SecurityEvent/GoogleSecOpsAlertNormalizer";
22
+ import { getJestSpyOn } from "../../../../../Spy";
23
+ import {
24
+ afterEach,
25
+ beforeEach,
26
+ describe,
27
+ expect,
28
+ jest,
29
+ test,
30
+ } from "@jest/globals";
31
+ import { secOpsSettings } from "./GoogleSecOpsConnectorFixtures";
32
+ import {
33
+ CONNECTION_ID,
34
+ DAY_MS,
35
+ GoogleSecOpsTenant,
36
+ HOUR_MS,
37
+ MINUTE_MS,
38
+ PROJECT_ID,
39
+ PollPersistence,
40
+ TenantDetection,
41
+ TenantRequest,
42
+ eventUidsOf,
43
+ findCheck,
44
+ keysAndStatuses,
45
+ lastUpdate,
46
+ requestWindow,
47
+ secOpsConnection,
48
+ storedResult,
49
+ streamReply,
50
+ stubPollPersistence,
51
+ googleError,
52
+ TENANT_CURATED_RULE_ID,
53
+ } from "./GoogleSecOpsPollingFixtures";
54
+
55
+ /*
56
+ * One Google SecOps poll at a time through the shared loop: the REAL
57
+ * SecurityEventConnectionPoller.executeConnection (and pollConnection) with
58
+ * the REAL GoogleSecOpsConnector and GoogleSecOpsClient over a simulated
59
+ * tenant, injected through PollerOverrides the way the generic poller suite
60
+ * injects its fake connector.
61
+ *
62
+ * These are the cases the retired GoogleSecOpsPoller, GoogleSecOpsPollerHardening,
63
+ * GoogleSecOpsThreePassPoller and GoogleSecOpsDiagnostics suites pinned on
64
+ * the poller side: which outcomes may move the cursor, what the window
65
+ * resolves to for a missing, stale, unreadable or future cursor, how records
66
+ * Google returns but OneUptime cannot import are counted, what a preview and
67
+ * a backfill may write, and that detections stay in the Google /
68
+ * Google SecOps dedupe scope connections carried over from that poller
69
+ * already imported under. Where the shared loop intentionally behaves
70
+ * differently, the test asserts the new behaviour and names the old one.
71
+ *
72
+ * The registry is mocked out, as in the generic poller suite, so importing
73
+ * the poller does not load every other provider's connector.
74
+ */
75
+
76
+ jest.mock(
77
+ "../../../../../../Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry",
78
+ () => {
79
+ return {
80
+ __esModule: true,
81
+ default: { getConnector: jest.fn() },
82
+ };
83
+ },
84
+ );
85
+
86
+ const NOW: Date = new Date("2026-09-10T12:00:00.000Z");
87
+ const CURSOR: string = "2026-09-10T11:55:00.000Z";
88
+
89
+ function iso(timeMs: number): string {
90
+ return new Date(timeMs).toISOString();
91
+ }
92
+
93
+ // A rule detection created and detected inside the window a CURSOR poll reads.
94
+ function recentDetection(
95
+ id: string,
96
+ changes: Partial<TenantDetection> = {},
97
+ ): TenantDetection {
98
+ return {
99
+ id,
100
+ createdMs: NOW.getTime() - 2 * MINUTE_MS,
101
+ detectionMs: NOW.getTime() - 3 * MINUTE_MS,
102
+ ...changes,
103
+ };
104
+ }
105
+
106
+ /*
107
+ * A Collection whose detection entry names a rule and carries a matched UDM
108
+ * sample event, so the finding row has entities rather than an empty shell.
109
+ */
110
+ function alertOneRecord(): JSONObject {
111
+ return {
112
+ id: "alert-1",
113
+ type: "RULE_DETECTION",
114
+ detectionTime: iso(NOW.getTime() - 3 * MINUTE_MS),
115
+ createdTime: iso(NOW.getTime() - 2 * MINUTE_MS),
116
+ detection: [
117
+ {
118
+ ruleName: "Suspicious PowerShell",
119
+ ruleId: "ru_1a2b",
120
+ severity: "HIGH",
121
+ alertState: "ALERTING",
122
+ },
123
+ ],
124
+ collectionElements: [
125
+ {
126
+ label: "e1",
127
+ references: [
128
+ {
129
+ event: {
130
+ metadata: {
131
+ eventType: "PROCESS_LAUNCH",
132
+ eventTimestamp: iso(NOW.getTime() - 4 * MINUTE_MS),
133
+ },
134
+ principal: {
135
+ hostname: "workstation-14",
136
+ ip: ["10.1.2.3"],
137
+ user: { userid: "jsmith" },
138
+ },
139
+ target: { ip: ["203.0.113.9"], port: 443 },
140
+ },
141
+ },
142
+ ],
143
+ },
144
+ ],
145
+ };
146
+ }
147
+
148
+ function durationOf(window: { startTime: string; endTime: string }): number {
149
+ return Date.parse(window.endTime) - Date.parse(window.startTime);
150
+ }
151
+
152
+ /*
153
+ * Every alerts-view request one poll made: the read of its own window and,
154
+ * for a scheduled poll whose window is shorter than the 24 hour late-alert
155
+ * lookback, the best-effort sweep of the day before that window.
156
+ */
157
+ function alertsRequestsFrom(
158
+ tenant: GoogleSecOpsTenant,
159
+ fromIndex: number = 0,
160
+ ): Array<TenantRequest> {
161
+ return tenant.requests
162
+ .slice(fromIndex)
163
+ .filter((request: TenantRequest): boolean => {
164
+ return request.route === "alerts";
165
+ });
166
+ }
167
+
168
+ // The alerts-view request of a poll that reads a whole day, so never sweeps.
169
+ function onlyAlertsRequest(
170
+ tenant: GoogleSecOpsTenant,
171
+ fromIndex: number = 0,
172
+ ): TenantRequest {
173
+ const alerts: Array<TenantRequest> = alertsRequestsFrom(tenant, fromIndex);
174
+ expect(alerts).toHaveLength(1);
175
+ return alerts[0]!;
176
+ }
177
+
178
+ /*
179
+ * Replaces the normalizer for the records whose id is listed, so a record
180
+ * fails the way a normalizer fault does. A hostile getter cannot survive
181
+ * the JSON the real client parses, so this is the seam the retired
182
+ * diagnostics suite used for the same purpose.
183
+ */
184
+ function failNormalizationFor(ids: Array<string>): void {
185
+ const normalize: (alert: JSONObject) => NormalizedSecurityEvent =
186
+ GoogleSecOpsAlertNormalizer.normalize.bind(GoogleSecOpsAlertNormalizer);
187
+ getJestSpyOn(GoogleSecOpsAlertNormalizer, "normalize").mockImplementation(((
188
+ alert: JSONObject,
189
+ ): NormalizedSecurityEvent => {
190
+ if (ids.includes(String(alert["id"]))) {
191
+ throw new Error("broken data");
192
+ }
193
+ return normalize(alert);
194
+ }) as never);
195
+ }
196
+
197
+ let tenant: GoogleSecOpsTenant;
198
+ let persistence: PollPersistence;
199
+
200
+ beforeEach(() => {
201
+ getJestSpyOn(OneUptimeDate, "getCurrentDate").mockReturnValue(NOW);
202
+ persistence = stubPollPersistence();
203
+ tenant = new GoogleSecOpsTenant();
204
+ });
205
+
206
+ afterEach(() => {
207
+ jest.restoreAllMocks();
208
+ (
209
+ SecurityEventConnectorRegistry.getConnector as unknown as jest.Mock
210
+ ).mockReset();
211
+ });
212
+
213
+ async function poll(
214
+ connection: SecurityEventConnection = secOpsConnection({ cursor: CURSOR }),
215
+ ): Promise<SecurityEventConnectionRunResult> {
216
+ return SecurityEventConnectionPoller.executeConnection(
217
+ connection,
218
+ { type: "poll" },
219
+ tenant.overrides(),
220
+ );
221
+ }
222
+
223
+ describe("Google SecOps through the shared poller: ingest and bookkeeping", () => {
224
+ test("ingests detections as Detection Finding rows and advances the cursor", async () => {
225
+ tenant.add(
226
+ recentDetection("alert-1", {
227
+ record: {
228
+ id: "alert-1",
229
+ detectionTime: iso(NOW.getTime() - 3 * MINUTE_MS),
230
+ createdTime: iso(NOW.getTime() - 2 * MINUTE_MS),
231
+ detection: [{ ruleName: "Brute force", severity: "HIGH" }],
232
+ },
233
+ }),
234
+ );
235
+
236
+ const ingested: number = await SecurityEventConnectionPoller.pollConnection(
237
+ secOpsConnection({ cursor: CURSOR }),
238
+ tenant.overrides(),
239
+ );
240
+
241
+ // Read by the created-time search AND the alerts view, imported once.
242
+ expect(ingested).toBe(1);
243
+ expect(persistence.insertedBatches).toHaveLength(1);
244
+ const row: JSONObject = persistence.insertedBatches[0]![0]!;
245
+ expect(row["classUid"]).toBe(2004);
246
+ expect(row["className"]).toBe("Detection Finding");
247
+ expect(row["ruleName"]).toBe("Brute force");
248
+ expect(row["projectId"]).toBe(PROJECT_ID.toString());
249
+ expect(row["vendorName"]).toBe("Google");
250
+ expect(row["productName"]).toBe("Google SecOps");
251
+
252
+ expect(persistence.updates).toHaveLength(1);
253
+ const written: JSONObject = persistence.updates[0]!.data;
254
+ expect(typeof written["cursor"]).toBe("string");
255
+ expect(written["cursor"]).toBe(NOW.toISOString());
256
+ expect(written["lastError"]).toBeNull();
257
+ });
258
+
259
+ test("the cursor written is exactly the endTime every pass was asked for", async () => {
260
+ // The alerts view answers in its real chunked envelope.
261
+ tenant.scripts.alerts = (): ReturnType<typeof streamReply> => {
262
+ return streamReply([
263
+ { alerts: { alerts: [alertOneRecord()] } },
264
+ { complete: true, progress: 1 },
265
+ ]);
266
+ };
267
+
268
+ const result: SecurityEventConnectionRunResult =
269
+ await poll(secOpsConnection());
270
+
271
+ const sent: { startTime: string; endTime: string } = requestWindow(
272
+ onlyAlertsRequest(tenant),
273
+ );
274
+ // The parameter really is an ISO instant, not some other rendering.
275
+ expect(new Date(sent.endTime).toISOString()).toBe(sent.endTime);
276
+ for (const request of [
277
+ ...tenant.requestsTo("search"),
278
+ ...tenant.requestsTo("curated"),
279
+ ]) {
280
+ expect(requestWindow(request)).toEqual(sent);
281
+ }
282
+
283
+ /*
284
+ * The curated pass opens with countAllCuratedRuleSetDetections, which
285
+ * carries its interval in a JSON body rather than the query string: it
286
+ * ends at the same instant, and reaches a week further back to find the
287
+ * curated rules the searches must name.
288
+ */
289
+ const interval: JSONObject = (
290
+ JSON.parse(
291
+ tenant.requestsTo("curatedCounts")[0]!.body || "{}",
292
+ ) as JSONObject
293
+ )["interval"] as JSONObject;
294
+ expect(interval).toEqual({
295
+ startTime: iso(Date.parse(sent.startTime) - 7 * DAY_MS),
296
+ endTime: sent.endTime,
297
+ });
298
+
299
+ const written: JSONObject = lastUpdate(persistence);
300
+ expect(written["cursor"]).toBe(sent.endTime);
301
+ expect(written["cursor"]).toBe(result.windowEnd);
302
+ expect((written["lastPolledAt"] as Date).getTime()).toBeGreaterThanOrEqual(
303
+ Date.parse(sent.endTime),
304
+ );
305
+ // ...and the window it closes really did start earlier than it ends.
306
+ expect(Date.parse(sent.startTime)).toBeLessThan(Date.parse(sent.endTime));
307
+ expect(result.ingestedCount).toBe(1);
308
+ });
309
+
310
+ test("no detections: no telemetry service resolution, no insert, one bookkeeping write, and the cursor still advances", async () => {
311
+ const ingested: number = await SecurityEventConnectionPoller.pollConnection(
312
+ secOpsConnection({ cursor: CURSOR }),
313
+ tenant.overrides(),
314
+ );
315
+
316
+ expect(ingested).toBe(0);
317
+ expect(OTelIngestService.telemetryServiceFromName).not.toHaveBeenCalled();
318
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
319
+ expect(persistence.updates).toHaveLength(1);
320
+ expect(persistence.updates[0]!.data["cursor"]).toBe(NOW.toISOString());
321
+ });
322
+
323
+ test("a recognized quiet stream is an empty, complete poll that clears lastError and stamps lastSuccessfulPollAt", async () => {
324
+ // Recognized chunk fields, zero alerts, complete; the searches answer {}.
325
+ tenant.scripts.alerts = (): ReturnType<typeof streamReply> => {
326
+ return streamReply([{ complete: true, progress: 1 }]);
327
+ };
328
+
329
+ await poll(secOpsConnection());
330
+
331
+ const written: JSONObject = lastUpdate(persistence);
332
+ expect(written).toEqual(
333
+ expect.objectContaining({
334
+ cursor: expect.any(String),
335
+ lastPolledAt: expect.any(Date),
336
+ lastPollResult: expect.any(Object),
337
+ }),
338
+ );
339
+ expect(written["cursor"]).toBe(
340
+ requestWindow(onlyAlertsRequest(tenant)).endTime,
341
+ );
342
+ expect(written["lastError"]).toBeNull();
343
+ expect(written["lastPollResult"]).toEqual(
344
+ expect.objectContaining({
345
+ status: "empty",
346
+ fetchedCount: 0,
347
+ ingestedCount: 0,
348
+ complete: true,
349
+ }),
350
+ );
351
+ expect(written["lastSuccessfulPollAt"]).toBeInstanceOf(Date);
352
+ expect(OTelIngestService.telemetryServiceFromName).not.toHaveBeenCalled();
353
+ });
354
+
355
+ test("a complete quiet poll echoes its run id and writes cursor, lastSuccessfulPollAt, lastPollResult and a null lastError", async () => {
356
+ const result: SecurityEventConnectionRunResult =
357
+ await SecurityEventConnectionPoller.executeConnection(
358
+ secOpsConnection({ cursor: CURSOR }),
359
+ { type: "poll", runId: "run-checkpoint-1" },
360
+ tenant.overrides(),
361
+ );
362
+
363
+ expect(result.status).toBe("empty");
364
+ expect(result.runId).toBe("run-checkpoint-1");
365
+ expect(lastUpdate(persistence)).toMatchObject({
366
+ cursor: NOW.toISOString(),
367
+ lastSuccessfulPollAt: NOW,
368
+ lastPollResult: result,
369
+ lastError: null,
370
+ });
371
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
372
+ });
373
+
374
+ test("the ingested count is returned and matches the rows written, with the unrecognized record counted as rejected", async () => {
375
+ tenant.add(recentDetection("alert-1", { record: alertOneRecord() }));
376
+ tenant.add(recentDetection("alert-2"));
377
+ /*
378
+ * A stream-chunk-shaped object handed back as a detection. Detected long
379
+ * ago, so only the created-time search returns it.
380
+ */
381
+ tenant.add({
382
+ id: "envelope",
383
+ createdMs: NOW.getTime() - MINUTE_MS,
384
+ detectionMs: NOW.getTime() - 30 * DAY_MS,
385
+ record: { progress: 0.5, complete: false },
386
+ });
387
+
388
+ const ingested: number = await SecurityEventConnectionPoller.pollConnection(
389
+ secOpsConnection({ cursor: CURSOR }),
390
+ tenant.overrides(),
391
+ );
392
+
393
+ expect(ingested).toBe(2);
394
+ expect(persistence.insertedBatches[0]!).toHaveLength(ingested);
395
+ expect(lastUpdate(persistence)["lastPollResult"]).toEqual(
396
+ expect.objectContaining({
397
+ fetchedCount: 3,
398
+ ingestedCount: 2,
399
+ rejectedCount: 1,
400
+ }),
401
+ );
402
+ });
403
+
404
+ test("a multi-detection batch is written in a single synchronous insert", async () => {
405
+ tenant.add(recentDetection("alert-1", { record: alertOneRecord() }));
406
+ tenant.add(recentDetection("alert-2"));
407
+
408
+ await poll();
409
+
410
+ expect(SecurityEventService.insertJsonRows).toHaveBeenCalledTimes(1);
411
+ expect(persistence.insertedBatches).toHaveLength(1);
412
+ expect(eventUidsOf(persistence.insertedBatches[0]!)).toEqual([
413
+ "alert-1",
414
+ "alert-2",
415
+ ]);
416
+ expect(persistence.insertOptions[0]).toEqual({
417
+ clickhouseSettings: { async_insert: 0, insert_distributed_sync: 1 },
418
+ });
419
+ });
420
+
421
+ test("threat intel is stamped on polled detections before the rows are built", async () => {
422
+ const enrichCalls: Array<{
423
+ projectId: ObjectID;
424
+ events: Array<NormalizedSecurityEvent>;
425
+ }> = [];
426
+ /*
427
+ * Replacing the implementation on the spy already installed, rather
428
+ * than spying again, so the restore returns the real method.
429
+ */
430
+ getJestSpyOn(
431
+ ThreatIntelEnricher,
432
+ "enrichNormalizedEvents",
433
+ ).mockImplementation(((data: {
434
+ projectId: ObjectID;
435
+ events: Array<NormalizedSecurityEvent>;
436
+ }): Promise<EnrichmentResult> => {
437
+ enrichCalls.push(data);
438
+ for (const event of data.events) {
439
+ event.attributes["threat.matched"] = "true";
440
+ }
441
+ return Promise.resolve({
442
+ eventsMatched: data.events.length,
443
+ valuesLookedUp: 1,
444
+ });
445
+ }) as never);
446
+ tenant.add(recentDetection("alert-1", { record: alertOneRecord() }));
447
+
448
+ await poll();
449
+
450
+ expect(enrichCalls).toHaveLength(1);
451
+ expect(enrichCalls[0]!.projectId.toString()).toBe(PROJECT_ID.toString());
452
+ expect(enrichCalls[0]!.events).toHaveLength(1);
453
+ expect(enrichCalls[0]!.events[0]!.classUid).toBe(2004);
454
+
455
+ /*
456
+ * The stamp survives into the row, which is only true if enrichment
457
+ * runs ahead of buildSecurityEventDbRow.
458
+ */
459
+ const row: JSONObject = persistence.insertedBatches[0]![0]!;
460
+ expect((row["attributes"] as JSONObject)["threat.matched"]).toBe("true");
461
+ expect(row["attributeKeys"] as Array<string>).toContain("threat.matched");
462
+ expect(row["principalHost"]).toBe("workstation-14");
463
+ });
464
+
465
+ test("the success path still clears lastError and advances a stale cursor", async () => {
466
+ const staleCursor: Date = new Date(NOW.getTime() - 30 * MINUTE_MS);
467
+
468
+ const ingested: number = await SecurityEventConnectionPoller.pollConnection(
469
+ secOpsConnection({ cursor: staleCursor.toISOString() }),
470
+ tenant.overrides(),
471
+ );
472
+
473
+ expect(ingested).toBe(0);
474
+ expect(persistence.updates).toHaveLength(1);
475
+ const written: JSONObject = persistence.updates[0]!.data;
476
+ expect(written["lastError"]).toBeNull();
477
+ expect(written["lastPolledAt"]).toBeInstanceOf(Date);
478
+ expect(new Date(written["cursor"] as string).getTime()).toBeGreaterThan(
479
+ staleCursor.getTime(),
480
+ );
481
+ });
482
+ });
483
+
484
+ describe("Google SecOps through the shared poller: windows and the cursor", () => {
485
+ test("the first poll looks back 24 hours, and a cursor poll overlaps the cursor by one minute", async () => {
486
+ await poll(secOpsConnection());
487
+
488
+ const first: { startTime: string; endTime: string } = requestWindow(
489
+ onlyAlertsRequest(tenant),
490
+ );
491
+ expect(durationOf(first)).toBe(DAY_MS);
492
+
493
+ const cursor: Date = new Date(NOW.getTime() - 5 * MINUTE_MS);
494
+ const before: number = tenant.requests.length;
495
+ await poll(secOpsConnection({ cursor: cursor.toISOString() }));
496
+
497
+ const alerts: Array<TenantRequest> = alertsRequestsFrom(tenant, before);
498
+ /*
499
+ * The six minute window, then the late-alert sweep of the rest of the
500
+ * day before it: a first poll already reads a whole day, so only the
501
+ * short cursor window is followed by one.
502
+ */
503
+ expect(alerts).toHaveLength(2);
504
+ const second: { startTime: string; endTime: string } = requestWindow(
505
+ alerts[0]!,
506
+ );
507
+ expect(cursor.getTime() - Date.parse(second.startTime)).toBe(MINUTE_MS);
508
+ expect(requestWindow(alerts[1]!)).toEqual({
509
+ startTime: iso(Date.parse(second.endTime) - DAY_MS),
510
+ endTime: second.startTime,
511
+ });
512
+ });
513
+
514
+ test("a week-old cursor reads one day past the cursor plus the one minute overlap", async () => {
515
+ const cursor: string = iso(NOW.getTime() - 7 * DAY_MS);
516
+
517
+ await poll(secOpsConnection({ cursor }));
518
+
519
+ /*
520
+ * Review finding alerts-view-budget-pins-cursor-forever (F1): the
521
+ * catch-up chunk is measured from the cursor rather than from the
522
+ * overlapped window start.
523
+ */
524
+ const window: { startTime: string; endTime: string } = requestWindow(
525
+ onlyAlertsRequest(tenant),
526
+ );
527
+ expect(durationOf(window)).toBe(DAY_MS + MINUTE_MS);
528
+ expect(Date.parse(window.endTime)).toBe(Date.parse(cursor) + DAY_MS);
529
+ });
530
+
531
+ test("an unreadable cursor polls the default 24 hour window, exactly like a first poll", async () => {
532
+ const windows: Array<{ startTime: string; endTime: string }> = [];
533
+
534
+ for (const cursor of [
535
+ undefined,
536
+ iso(NOW.getTime() - 7 * DAY_MS),
537
+ "garbage",
538
+ ]) {
539
+ const before: number = tenant.requests.length;
540
+ await poll(secOpsConnection(cursor === undefined ? {} : { cursor }));
541
+ windows.push(requestWindow(onlyAlertsRequest(tenant, before)));
542
+ }
543
+
544
+ const [firstPoll, stale, garbage] = windows;
545
+ expect(durationOf(firstPoll!)).toBe(DAY_MS);
546
+ // F1: a day of new time past the cursor plus the overlap minute before it.
547
+ expect(durationOf(stale!)).toBe(DAY_MS + MINUTE_MS);
548
+ /*
549
+ * An unreadable cursor means "no usable cursor", which is what a first
550
+ * poll means: it ends now, rather than a day after wherever the garbage
551
+ * would have pointed.
552
+ */
553
+ expect(durationOf(garbage!)).toBe(durationOf(firstPoll!));
554
+ expect(garbage!.endTime).toBe(firstPoll!.endTime);
555
+ expect(Date.parse(stale!.endTime)).toBeLessThan(
556
+ Date.parse(firstPoll!.endTime),
557
+ );
558
+ });
559
+
560
+ test("an unreadable cursor is reported in the persisted diagnostics", async () => {
561
+ await poll(secOpsConnection({ cursor: "2026-13-45T99:99:99Z" }));
562
+
563
+ expect(storedResult(lastUpdate(persistence)).warnings.join(" ")).toMatch(
564
+ /cursor is unreadable/,
565
+ );
566
+ });
567
+
568
+ test("a cursor in the future never produces an inverted time range", async () => {
569
+ await poll(secOpsConnection());
570
+ const firstPoll: { startTime: string; endTime: string } = requestWindow(
571
+ onlyAlertsRequest(tenant),
572
+ );
573
+
574
+ // Clock skew on the writer, or a restored backup.
575
+ const before: number = tenant.requests.length;
576
+ await poll(secOpsConnection({ cursor: iso(NOW.getTime() + HOUR_MS) }));
577
+ const future: { startTime: string; endTime: string } = requestWindow(
578
+ onlyAlertsRequest(tenant, before),
579
+ );
580
+
581
+ expect(Date.parse(future.startTime)).toBeLessThan(
582
+ Date.parse(future.endTime),
583
+ );
584
+ expect(durationOf(future)).toBe(durationOf(firstPoll));
585
+ expect(persistence.logs.warn.join(" ")).toMatch(/cursor is in the future/);
586
+ });
587
+
588
+ test("a stale cursor catches up from its original boundary without discarding the gap", async () => {
589
+ const cursor: string = iso(NOW.getTime() - 7 * DAY_MS);
590
+
591
+ await poll(secOpsConnection({ cursor }));
592
+
593
+ const stale: { startTime: string; endTime: string } = requestWindow(
594
+ onlyAlertsRequest(tenant),
595
+ );
596
+ // F1: a day past the cursor, plus the overlap minute before it.
597
+ expect(durationOf(stale)).toBe(DAY_MS + MINUTE_MS);
598
+ expect(Date.parse(stale.endTime)).toBe(Date.parse(cursor) + DAY_MS);
599
+ expect(Date.parse(stale.startTime)).toBe(Date.parse(cursor) - MINUTE_MS);
600
+ expect(Date.parse(stale.endTime)).toBeLessThan(NOW.getTime() - 5 * DAY_MS);
601
+ const written: JSONObject = lastUpdate(persistence);
602
+ expect(written["cursor"]).toBe(stale.endTime);
603
+ expect(storedResult(written).warnings.join(" ")).toMatch(/Catching up/);
604
+ });
605
+
606
+ test("stale cursors process the earliest backlog instead of skipping to yesterday", async () => {
607
+ const result: SecurityEventConnectionRunResult = await poll(
608
+ secOpsConnection({ cursor: "2026-09-01T12:00:00.000Z" }),
609
+ );
610
+
611
+ expect(result.windowStart).toBe("2026-09-01T11:59:00.000Z");
612
+ // F1: the 24 hour chunk is measured from the cursor, not the overlapped start.
613
+ expect(result.windowEnd).toBe("2026-09-02T12:00:00.000Z");
614
+ expect(lastUpdate(persistence)["cursor"]).toBe(result.windowEnd);
615
+ });
616
+ });
617
+
618
+ describe("Google SecOps through the shared poller: records that cannot be imported", () => {
619
+ test("rejected objects are counted and warned but do not hold the cursor", async () => {
620
+ tenant.add(recentDetection("ok"));
621
+ tenant.add({
622
+ id: "envelope",
623
+ createdMs: NOW.getTime() - MINUTE_MS,
624
+ detectionMs: NOW.getTime() - 30 * DAY_MS,
625
+ record: { arbitrary: "envelope" },
626
+ });
627
+
628
+ const result: SecurityEventConnectionRunResult = await poll();
629
+
630
+ expect(result).toMatchObject({
631
+ status: "success",
632
+ complete: true,
633
+ rejectedCount: 1,
634
+ ingestedCount: 1,
635
+ });
636
+ /*
637
+ * The retired poller named this check "Normalize detections" and warned
638
+ * that rejected objects "do not hold the poll cursor". The shared loop
639
+ * reports it on its summary read check and words the warning itself.
640
+ */
641
+ expect(findCheck(result.checks, "read").status).toBe("warn");
642
+ expect(result.warnings).toContain(
643
+ "1 returned records were discarded because they do not look like Google SecOps detections.",
644
+ );
645
+ expect(lastUpdate(persistence)["cursor"]).toBe(NOW.toISOString());
646
+ expect(lastUpdate(persistence)["lastError"]).toBeNull();
647
+ });
648
+
649
+ test("unrecognized payloads in the alerts view are counted and warned without holding the cursor", async () => {
650
+ tenant.scripts.alerts = (): ReturnType<typeof streamReply> => {
651
+ return streamReply([
652
+ {
653
+ alerts: {
654
+ alerts: [
655
+ { arbitrary: "envelope" },
656
+ {
657
+ id: "alert-1",
658
+ detectionTime: iso(NOW.getTime() - 3 * MINUTE_MS),
659
+ detection: [{ ruleName: "Suspicious sign-in" }],
660
+ },
661
+ ],
662
+ },
663
+ complete: true,
664
+ progress: 1,
665
+ baselineAlertsCount: 2,
666
+ filteredAlertsCount: 2,
667
+ },
668
+ ]);
669
+ };
670
+
671
+ const result: SecurityEventConnectionRunResult = await poll();
672
+
673
+ /*
674
+ * A permanently unrecognizable object used to hold the cursor, which
675
+ * pinned the window until the 24 hour chunk could never reach the
676
+ * present. It is counted, warned, and shown as a "warn" check.
677
+ */
678
+ expect(result).toMatchObject({
679
+ status: "success",
680
+ complete: true,
681
+ rejectedCount: 1,
682
+ ingestedCount: 1,
683
+ });
684
+ expect(result.warnings.join(" ")).toMatch(/discarded/);
685
+ expect(findCheck(result.checks, "read").status).toBe("warn");
686
+ expect(lastUpdate(persistence)["cursor"]).toBe(NOW.toISOString());
687
+ });
688
+
689
+ test("a normalization failure still holds the cursor", async () => {
690
+ failNormalizationFor(["poison"]);
691
+ tenant.add(recentDetection("poison"));
692
+ tenant.add(recentDetection("ok"));
693
+
694
+ const result: SecurityEventConnectionRunResult = await poll();
695
+
696
+ expect(result).toMatchObject({
697
+ status: "partial",
698
+ failedCount: 1,
699
+ ingestedCount: 1,
700
+ complete: false,
701
+ });
702
+ // The retired poller's "Normalize detections: failed" is the read check now.
703
+ expect(findCheck(result.checks, "read").status).toBe("fail");
704
+ expect(lastUpdate(persistence)).not.toHaveProperty("cursor");
705
+ });
706
+
707
+ test("detections that all fail to normalize hold the first poll at its anchor rather than skipping the window", async () => {
708
+ failNormalizationFor(["poison-1", "poison-2"]);
709
+ tenant.add({
710
+ id: "poison-1",
711
+ createdMs: NOW.getTime() - 2 * HOUR_MS,
712
+ detectionMs: NOW.getTime() - 2 * HOUR_MS,
713
+ });
714
+ tenant.add({
715
+ id: "poison-2",
716
+ createdMs: NOW.getTime() - HOUR_MS,
717
+ detectionMs: NOW.getTime() - HOUR_MS,
718
+ });
719
+
720
+ const ingested: number = await SecurityEventConnectionPoller.pollConnection(
721
+ secOpsConnection(),
722
+ tenant.overrides(),
723
+ );
724
+
725
+ expect(ingested).toBe(0);
726
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
727
+ const written: JSONObject = lastUpdate(persistence);
728
+ expect(written["lastPollResult"]).toEqual(
729
+ expect.objectContaining({ complete: false }),
730
+ );
731
+ expect(written["lastSuccessfulPollAt"]).toBeUndefined();
732
+ const result: SecurityEventConnectionRunResult = storedResult(written);
733
+ expect(result.status).toBe("partial");
734
+ expect(result.failedCount).toBe(2);
735
+ expect(Date.parse(String(written["cursor"])) - MINUTE_MS).toBe(
736
+ Date.parse(result.windowStart),
737
+ );
738
+ });
739
+
740
+ test("a mixed normalization failure preserves retry coverage even after other records import", async () => {
741
+ failNormalizationFor(["broken"]);
742
+ tenant.add(recentDetection("valid"));
743
+ tenant.add(recentDetection("broken"));
744
+
745
+ const result: SecurityEventConnectionRunResult = await poll();
746
+
747
+ expect(result).toMatchObject({
748
+ status: "partial",
749
+ ingestedCount: 1,
750
+ failedCount: 1,
751
+ complete: false,
752
+ });
753
+ expect(lastUpdate(persistence)).not.toHaveProperty("cursor");
754
+ });
755
+
756
+ test("a partial alerts-view stream imports what arrived but holds the whole prior cursor", async () => {
757
+ // The stream ends without complete=true on every attempt the client makes.
758
+ tenant.scripts.alerts = (): ReturnType<typeof streamReply> => {
759
+ return streamReply([
760
+ {
761
+ alerts: {
762
+ alerts: [
763
+ {
764
+ id: "alert-1",
765
+ detectionTime: iso(NOW.getTime() - 3 * MINUTE_MS),
766
+ detection: [{ ruleName: "Suspicious sign-in" }],
767
+ },
768
+ ],
769
+ },
770
+ progress: 0.5,
771
+ },
772
+ ]);
773
+ };
774
+
775
+ const result: SecurityEventConnectionRunResult = await poll();
776
+
777
+ expect(result.status).toBe("partial");
778
+ expect(result.ingestedCount).toBe(1);
779
+ /*
780
+ * The client re-issued the unfinished GET before handing back what it
781
+ * had: three attempts for the window read, and three more for the
782
+ * late-alert sweep that follows it, which the same script answers.
783
+ */
784
+ expect(tenant.requestsTo("alerts")).toHaveLength(6);
785
+ expect(lastUpdate(persistence)).not.toHaveProperty("cursor");
786
+ expect(lastUpdate(persistence)).not.toHaveProperty("lastSuccessfulPollAt");
787
+ expect(lastUpdate(persistence)["lastError"]).toMatch(/complete/);
788
+ });
789
+
790
+ test("a partial first poll anchors its window so a delayed retry re-covers it from the same start in half the chunk", async () => {
791
+ tenant.scripts.alerts = (): ReturnType<typeof streamReply> => {
792
+ return streamReply([{ progress: 0.5 }]);
793
+ };
794
+ const item: SecurityEventConnection = secOpsConnection();
795
+
796
+ const first: SecurityEventConnectionRunResult = await poll(item);
797
+
798
+ expect(first.chunkMinutes).toBe(24 * 60);
799
+ expect(first.nextChunkMinutes).toBe(12 * 60);
800
+ item.cursor = String(lastUpdate(persistence)["cursor"]);
801
+ // The row is reloaded with the result it was written with.
802
+ item.lastPollResult = JSON.parse(
803
+ JSON.stringify(lastUpdate(persistence)["lastPollResult"]),
804
+ ) as JSONObject;
805
+ delete tenant.scripts.alerts;
806
+ getJestSpyOn(OneUptimeDate, "getCurrentDate").mockReturnValue(
807
+ new Date("2026-09-10T14:00:00.000Z"),
808
+ );
809
+
810
+ const retry: SecurityEventConnectionRunResult = await poll(item);
811
+
812
+ expect(retry.windowStart).toBe(first.windowStart);
813
+ /*
814
+ * Review finding alerts-view-budget-pins-cursor-forever (F1): the retry
815
+ * keeps the start and reads half the chunk, measured from the anchored
816
+ * cursor.
817
+ */
818
+ expect(retry.windowEnd).toBe("2026-09-10T00:01:00.000Z");
819
+ expect(retry.chunkMinutes).toBe(12 * 60);
820
+ /*
821
+ * The retired poller worded this "12 hour windows"; the shared loop
822
+ * names any chunk shorter than a day in minutes.
823
+ */
824
+ expect(retry.warnings).toContain(
825
+ "Catching up from the saved cursor in 720 minute windows. Later records will be fetched by subsequent polls.",
826
+ );
827
+ expect(lastUpdate(persistence)["cursor"]).toBe("2026-09-10T00:01:00.000Z");
828
+ });
829
+ });
830
+
831
+ describe("Google SecOps through the shared poller: the three passes on the stored run", () => {
832
+ test("per-pass checks and providerDetails are kept on the run result and on the stored lastPollResult", async () => {
833
+ // Window [11:54, 12:00). a and b are rule detections created in it.
834
+ tenant.add({
835
+ id: "a",
836
+ createdMs: Date.parse("2026-09-10T11:56:00.000Z"),
837
+ detectionMs: Date.parse("2026-09-10T11:55:30.000Z"),
838
+ });
839
+ tenant.add({
840
+ id: "b",
841
+ createdMs: Date.parse("2026-09-10T11:57:00.000Z"),
842
+ detectionMs: Date.parse("2026-09-10T11:56:00.000Z"),
843
+ });
844
+ // c is a curated rule detection.
845
+ tenant.add({
846
+ id: "c",
847
+ curated: true,
848
+ createdMs: Date.parse("2026-09-10T11:58:00.000Z"),
849
+ detectionMs: Date.parse("2026-09-10T11:57:00.000Z"),
850
+ });
851
+ // d was created before the window: only the alerts view sees it.
852
+ tenant.add({
853
+ id: "d",
854
+ createdMs: Date.parse("2026-09-10T11:30:00.000Z"),
855
+ detectionMs: Date.parse("2026-09-10T11:59:00.000Z"),
856
+ });
857
+
858
+ const result: SecurityEventConnectionRunResult = await poll();
859
+
860
+ expect(result).toMatchObject({
861
+ status: "success",
862
+ complete: true,
863
+ fetchedCount: 4,
864
+ ingestedCount: 4,
865
+ /*
866
+ * One rule search, the curated rule counts, one curated search for the
867
+ * single rule those counts named, the alerts view over the window, and
868
+ * the late-alert sweep of the day before it.
869
+ */
870
+ requestCount: 5,
871
+ });
872
+ /*
873
+ * The retired poller stored these as "Validate configuration:success",
874
+ * the three pass names, "Normalize detections" and "Import detections".
875
+ * The pass names are unchanged; the statuses, the late-alert sweep and
876
+ * the last two steps are the shared loop's.
877
+ */
878
+ expect(
879
+ result.checks.map(
880
+ (check: { key: string; name: string; status: string }): string => {
881
+ return `${check.key}|${check.name}|${check.status}`;
882
+ },
883
+ ),
884
+ ).toEqual([
885
+ "configuration|Validate configuration|pass",
886
+ "read-rule-detections|Read rule detections by created time|pass",
887
+ "read-curated-detections|Read curated rule detections by created time|pass",
888
+ "read-alerts-view|Read alerts view by detection time|pass",
889
+ "read-late-alerts-view|Read late alerts by detection time|pass",
890
+ "read|Read detections from Google SecOps|pass",
891
+ "import|Import records|pass",
892
+ ]);
893
+ expect(result.providerDetails).toEqual({
894
+ basis: "created-time",
895
+ sourceCounts: {
896
+ ruleDetections: 2,
897
+ curatedDetections: 1,
898
+ alertsView: 4,
899
+ // Nothing was detected in the day before the window.
900
+ lateAlertsView: 0,
901
+ },
902
+ // The one curated rule the counts reported detections for.
903
+ curatedRulesWithDetections: 1,
904
+ creationLag: { measured: 4, lateCount: 0, maxLagMinutes: 1 },
905
+ includeNonAlertingDetections: false,
906
+ });
907
+
908
+ const stored: SecurityEventConnectionRunResult = storedResult(
909
+ lastUpdate(persistence),
910
+ );
911
+ expect(keysAndStatuses(stored.checks)).toEqual(
912
+ keysAndStatuses(result.checks),
913
+ );
914
+ expect(stored.providerDetails).toEqual(result.providerDetails);
915
+ expect(eventUidsOf(persistence.insertedBatches[0]!)).toEqual([
916
+ "a",
917
+ "b",
918
+ "c",
919
+ "d",
920
+ ]);
921
+ });
922
+
923
+ test("a curated route answering HTTP 403 is a warning check in the run and the poll still completes", async () => {
924
+ /*
925
+ * A tenant without curated rule access is refused at the curated pass's
926
+ * first request, countAllCuratedRuleSetDetections: that is what names
927
+ * the rules legacySearchCuratedDetections must be given, so no curated
928
+ * search is even attempted.
929
+ */
930
+ tenant.scripts.curatedCounts = (): ReturnType<typeof googleError> => {
931
+ return googleError(
932
+ 403,
933
+ "PERMISSION_DENIED",
934
+ "Caller does not have permission 'chronicle.curatedRuleSetCategories.countAllCuratedRuleSetDetections'.",
935
+ );
936
+ };
937
+ tenant.add(recentDetection("rule-detection"));
938
+
939
+ const result: SecurityEventConnectionRunResult = await poll();
940
+
941
+ expect(result).toMatchObject({
942
+ status: "success",
943
+ complete: true,
944
+ ingestedCount: 1,
945
+ });
946
+ const curated: ReturnType<typeof findCheck> = findCheck(
947
+ result.checks,
948
+ "read-curated-detections",
949
+ );
950
+ expect(curated).toMatchObject({
951
+ name: "Read curated rule detections by created time",
952
+ status: "warn",
953
+ details: { httpStatus: 403 },
954
+ });
955
+ expect(curated.remediation).toContain("Curated (Google-authored)");
956
+ expect(curated.message).toContain(
957
+ "Google SecOps curated rule detection counts failed (HTTP 403)",
958
+ );
959
+ expect(result.warnings).toContain(
960
+ "Curated rule detections could not be read (HTTP 403); this tenant may not have curated rule access. Rule detections and the alerts view were still read.",
961
+ );
962
+ // No curated rule could be named, so no curated search was sent.
963
+ expect(tenant.requestsTo("curated")).toHaveLength(0);
964
+ /*
965
+ * The alerts view still ran after the curated pass degraded: the
966
+ * window read, then the late-alert sweep of the day before it.
967
+ */
968
+ expect(tenant.requestsTo("alerts")).toHaveLength(2);
969
+ const written: JSONObject = lastUpdate(persistence);
970
+ expect(written["cursor"]).toBe(NOW.toISOString());
971
+ expect(written["lastError"]).toBeNull();
972
+ expect(
973
+ findCheck(storedResult(written).checks, "read-curated-detections").status,
974
+ ).toBe("warn");
975
+ });
976
+
977
+ test("pollIntervalInMinutes reaches the connector's creation-lag measurement", async () => {
978
+ // Created twenty minutes after its detection time, inside the created-time window.
979
+ tenant.add({
980
+ id: "late",
981
+ createdMs: Date.parse("2026-09-10T11:58:00.000Z"),
982
+ detectionMs: Date.parse("2026-09-10T11:38:00.000Z"),
983
+ });
984
+
985
+ const hourly: SecurityEventConnectionRunResult = await poll(
986
+ secOpsConnection({ cursor: CURSOR, pollIntervalInMinutes: 30 }),
987
+ );
988
+ const everyFive: SecurityEventConnectionRunResult = await poll(
989
+ secOpsConnection({ cursor: CURSOR, pollIntervalInMinutes: 5 }),
990
+ );
991
+
992
+ // Within 30 minutes plus the one minute grace: measured, not late.
993
+ expect(hourly.providerDetails?.["creationLag"]).toEqual({
994
+ measured: 1,
995
+ lateCount: 0,
996
+ maxLagMinutes: 20,
997
+ });
998
+ expect(hourly.warnings.join(" ")).not.toMatch(/created more than/);
999
+ // Beyond 5 minutes plus the grace: late, and the warning says why.
1000
+ expect(everyFive.providerDetails?.["creationLag"]).toEqual({
1001
+ measured: 1,
1002
+ lateCount: 1,
1003
+ maxLagMinutes: 20,
1004
+ });
1005
+ expect(everyFive.warnings).toContain(
1006
+ "1 of 1 detections were created more than 6 minutes after their detection time (up to 20 minutes). This is why the connector polls by created time: a cursor over detection time would already have moved past them.",
1007
+ );
1008
+ // Informational: both runs are complete and move the cursor.
1009
+ expect(hourly.status).toBe("success");
1010
+ expect(everyFive.complete).toBe(true);
1011
+ });
1012
+ });
1013
+
1014
+ describe("Google SecOps through the shared poller: preview and backfill", () => {
1015
+ test.each([
1016
+ ["bad", NOW.toISOString()],
1017
+ [NOW.toISOString(), "bad"],
1018
+ [NOW.toISOString(), NOW.toISOString()],
1019
+ [NOW.toISOString(), "2026-09-09T00:00:00Z"],
1020
+ ["2026-09-01T00:00:00Z", NOW.toISOString()],
1021
+ ["2026-09-09T00:00:00Z", "2026-09-11T00:00:00Z"],
1022
+ ])(
1023
+ "rejects invalid or excessive preview range %s to %s",
1024
+ async (startTime: string, endTime: string) => {
1025
+ await expect(
1026
+ SecurityEventConnectionPoller.executeConnection(
1027
+ secOpsConnection({ cursor: CURSOR }),
1028
+ { type: "preview", startTime, endTime },
1029
+ tenant.overrides(),
1030
+ ),
1031
+ ).rejects.toThrow(/seven days/);
1032
+ // Nothing, not even the token exchange, reached Google.
1033
+ expect(tenant.requests).toHaveLength(0);
1034
+ expect(persistence.updates).toHaveLength(0);
1035
+ },
1036
+ );
1037
+
1038
+ test("accepts an exact seven day historical range", async () => {
1039
+ const result: SecurityEventConnectionRunResult =
1040
+ await SecurityEventConnectionPoller.executeConnection(
1041
+ secOpsConnection({ cursor: CURSOR }),
1042
+ {
1043
+ type: "preview",
1044
+ startTime: "2026-09-03T12:00:00Z",
1045
+ endTime: NOW.toISOString(),
1046
+ },
1047
+ tenant.overrides(),
1048
+ );
1049
+
1050
+ expect(result.status).toBe("empty");
1051
+ });
1052
+
1053
+ test("a preview reads the search passes by created and detection time, reports the detection-time basis and never moves the cursor", async () => {
1054
+ tenant.add({
1055
+ id: "x",
1056
+ alerting: false,
1057
+ createdMs: Date.parse("2026-09-10T04:16:00.000Z"),
1058
+ detectionMs: Date.parse("2026-09-09T01:30:00.000Z"),
1059
+ });
1060
+ /*
1061
+ * A curated rule that fired earlier in the week, before the previewed
1062
+ * range: the counts still report it, so the curated pass searches it by
1063
+ * both bases and reads nothing for this range.
1064
+ */
1065
+ tenant.add({
1066
+ id: "curated-last-week",
1067
+ curated: true,
1068
+ createdMs: Date.parse("2026-09-05T00:00:00.000Z"),
1069
+ detectionMs: Date.parse("2026-09-05T00:00:00.000Z"),
1070
+ });
1071
+
1072
+ const result: SecurityEventConnectionRunResult =
1073
+ await SecurityEventConnectionPoller.executeConnection(
1074
+ secOpsConnection({ cursor: CURSOR, alertingOnly: false }),
1075
+ {
1076
+ type: "preview",
1077
+ startTime: "2026-09-09T00:00:00.000Z",
1078
+ endTime: NOW.toISOString(),
1079
+ },
1080
+ tenant.overrides(secOpsSettings({ alertingOnly: false })),
1081
+ );
1082
+
1083
+ /*
1084
+ * The curated searches carry the one rule id the counts named:
1085
+ * legacySearchCuratedDetections has no wildcard, so the "-" the rule
1086
+ * search reads every rule with would answer 200 and no detections.
1087
+ */
1088
+ expect(
1089
+ tenant.requests
1090
+ .filter((request: TenantRequest): boolean => {
1091
+ return request.route === "search" || request.route === "curated";
1092
+ })
1093
+ .map((request: TenantRequest): string => {
1094
+ return `${request.route}:${request.url.searchParams.get("listBasis")}:${request.url.searchParams.get("alertState")}:${request.url.searchParams.get("ruleId")}`;
1095
+ }),
1096
+ ).toEqual([
1097
+ "search:CREATED_TIME:null:-",
1098
+ "search:DETECTION_TIME:null:-",
1099
+ `curated:CREATED_TIME:null:${TENANT_CURATED_RULE_ID}`,
1100
+ `curated:DETECTION_TIME:null:${TENANT_CURATED_RULE_ID}`,
1101
+ ]);
1102
+ // The counts that named it reach a week before the previewed range.
1103
+ expect(
1104
+ JSON.parse(
1105
+ tenant.requestsTo("curatedCounts")[0]!.body || "{}",
1106
+ ) as JSONObject,
1107
+ ).toEqual({
1108
+ interval: {
1109
+ startTime: "2026-09-02T00:00:00.000Z",
1110
+ endTime: NOW.toISOString(),
1111
+ },
1112
+ });
1113
+ expect(
1114
+ tenant
1115
+ .requestsTo("alerts")[0]!
1116
+ .url.searchParams.get("includeNonAlertingDetections"),
1117
+ ).toBe("ALERTS_FEATURE_PREFERENCE_ENABLED");
1118
+ expect(result.providerDetails).toMatchObject({
1119
+ basis: "detection-time",
1120
+ sourceCounts: { ruleDetections: 2, curatedDetections: 0, alertsView: 1 },
1121
+ includeNonAlertingDetections: true,
1122
+ });
1123
+ // The same record read by both bases and the alerts view is one record.
1124
+ expect(result.fetchedCount).toBe(1);
1125
+ expect(findCheck(result.checks, "read-rule-detections").name).toBe(
1126
+ "Read rule detections by created and detection time",
1127
+ );
1128
+ expect(result.samples).toEqual([
1129
+ {
1130
+ id: "x",
1131
+ title: "Rule for x",
1132
+ severity: "High",
1133
+ createdTime: "2026-09-10T04:16:00.000Z",
1134
+ eventTime: "2026-09-09T01:30:00.000Z",
1135
+ isAlert: false,
1136
+ },
1137
+ ]);
1138
+ expect(result.chunkMinutes).toBeUndefined();
1139
+ expect(persistence.updates).toHaveLength(0);
1140
+ expect(persistence.insertedBatches).toHaveLength(0);
1141
+ expect(persistence.dedupeLookups).toHaveLength(0);
1142
+ expect(Semaphore.lock).not.toHaveBeenCalled();
1143
+ });
1144
+
1145
+ test("backfill imports source event timestamps, reads both bases and records the event range without changing poll state", async () => {
1146
+ tenant.add({
1147
+ id: "alert-1",
1148
+ alerting: false,
1149
+ createdMs: Date.parse("2026-09-10T04:16:00.000Z"),
1150
+ detectionMs: Date.parse("2026-09-09T01:30:00.000Z"),
1151
+ });
1152
+
1153
+ const result: SecurityEventConnectionRunResult =
1154
+ await SecurityEventConnectionPoller.executeConnection(
1155
+ secOpsConnection({ cursor: CURSOR, alertingOnly: false }),
1156
+ {
1157
+ type: "backfill",
1158
+ startTime: "2026-09-09T00:00:00.000Z",
1159
+ endTime: NOW.toISOString(),
1160
+ },
1161
+ tenant.overrides(secOpsSettings({ alertingOnly: false })),
1162
+ );
1163
+
1164
+ expect(
1165
+ tenant
1166
+ .requestsTo("search")
1167
+ .map((request: TenantRequest): string | null => {
1168
+ return request.url.searchParams.get("listBasis");
1169
+ }),
1170
+ ).toEqual(["CREATED_TIME", "DETECTION_TIME"]);
1171
+ expect(result.ingestedCount).toBe(1);
1172
+ expect(result.eventTimeStart).toBe("2026-09-09T01:30:00.000Z");
1173
+ expect(result.eventTimeEnd).toBe(result.eventTimeStart);
1174
+ // Only lastEventIngestedAt: the cursor and the poll bookkeeping are untouched.
1175
+ expect(persistence.updates).toHaveLength(1);
1176
+ expect(lastUpdate(persistence)).toEqual({ lastEventIngestedAt: NOW });
1177
+ const attributes: JSONObject = persistence.insertedBatches[0]![0]![
1178
+ "attributes"
1179
+ ] as JSONObject;
1180
+ /*
1181
+ * The retired poller stamped oneuptime.google_secops.connection_id. The
1182
+ * shared loop stamps its own attribute and leaves eventAttributeKey
1183
+ * unset; only runs carried over by the data migration name the legacy
1184
+ * key.
1185
+ */
1186
+ expect(attributes[SECURITY_CONNECTION_ID_ATTRIBUTE]).toBe(
1187
+ CONNECTION_ID.toString(),
1188
+ );
1189
+ expect(attributes).not.toHaveProperty(
1190
+ LEGACY_GOOGLE_SECOPS_CONNECTION_ID_ATTRIBUTE,
1191
+ );
1192
+ expect(result.eventAttributeKey).toBeUndefined();
1193
+ });
1194
+ });
1195
+
1196
+ describe("Google SecOps through the shared poller: duplicates and storage", () => {
1197
+ test("the dedupe lookup is scoped to Google / Google SecOps and the telemetry service is Google SecOps", async () => {
1198
+ // Imported by the retired poller under the same scope.
1199
+ persistence.stored.add("already");
1200
+ tenant.add(recentDetection("already"));
1201
+ tenant.add(
1202
+ recentDetection("new", { createdMs: NOW.getTime() - MINUTE_MS }),
1203
+ );
1204
+
1205
+ const result: SecurityEventConnectionRunResult = await poll();
1206
+
1207
+ expect(result.duplicateCount).toBe(1);
1208
+ expect(result.ingestedCount).toBe(1);
1209
+ expect(persistence.dedupeLookups).toHaveLength(1);
1210
+ expect(persistence.dedupeLookups[0]).toEqual({
1211
+ projectId: PROJECT_ID,
1212
+ vendorName: "Google",
1213
+ productName: "Google SecOps",
1214
+ ids: expect.arrayContaining(["already", "new"]),
1215
+ });
1216
+ expect(OTelIngestService.telemetryServiceFromName).toHaveBeenCalledWith({
1217
+ serviceName: "Google SecOps",
1218
+ projectId: PROJECT_ID,
1219
+ });
1220
+ expect(eventUidsOf(persistence.insertedBatches[0]!)).toEqual(["new"]);
1221
+ });
1222
+
1223
+ test("replaying a previously imported detection skips its persisted event uid", async () => {
1224
+ persistence.stored.add("alert-1");
1225
+ tenant.add(recentDetection("alert-1"));
1226
+
1227
+ const result: SecurityEventConnectionRunResult = await poll();
1228
+
1229
+ expect(result).toMatchObject({
1230
+ ingestedCount: 0,
1231
+ duplicateCount: 1,
1232
+ complete: true,
1233
+ });
1234
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
1235
+ expect(OTelIngestService.telemetryServiceFromName).not.toHaveBeenCalled();
1236
+ expect(SecurityEventDedupe.findExistingEventUids).toHaveBeenCalledWith({
1237
+ projectId: PROJECT_ID,
1238
+ vendorName: "Google",
1239
+ productName: "Google SecOps",
1240
+ ids: ["alert-1"],
1241
+ });
1242
+ });
1243
+
1244
+ test("two overlapping polls only insert each detection once", async () => {
1245
+ tenant.add(recentDetection("alert-1"));
1246
+
1247
+ const first: SecurityEventConnectionRunResult = await poll();
1248
+ const second: SecurityEventConnectionRunResult = await poll();
1249
+
1250
+ expect(first.ingestedCount).toBe(1);
1251
+ expect(second.duplicateCount).toBe(1);
1252
+ expect(second.ingestedCount).toBe(0);
1253
+ expect(persistence.insertedBatches).toHaveLength(1);
1254
+ expect(persistence.stored).toEqual(new Set(["alert-1"]));
1255
+ });
1256
+
1257
+ test("a failed insert records the failure and never advances the cursor or reports imported events", async () => {
1258
+ getJestSpyOn(SecurityEventService, "insertJsonRows").mockRejectedValue(
1259
+ new Error("Event storage unavailable") as never,
1260
+ );
1261
+ tenant.add(recentDetection("alert-1"));
1262
+
1263
+ const result: SecurityEventConnectionRunResult = await poll();
1264
+
1265
+ expect(result).toMatchObject({
1266
+ status: "failed",
1267
+ complete: false,
1268
+ ingestedCount: 0,
1269
+ });
1270
+ expect(lastUpdate(persistence)).not.toHaveProperty("cursor");
1271
+ expect(result.error).toMatch(/storage unavailable/);
1272
+ expect(findCheck(result.checks, "failure").name).toBe("Import records");
1273
+ expect(Semaphore.release).toHaveBeenCalledTimes(1);
1274
+ });
1275
+
1276
+ test("a failed duplicate lookup does not insert potentially duplicate records", async () => {
1277
+ getJestSpyOn(
1278
+ SecurityEventDedupe,
1279
+ "findExistingEventUids",
1280
+ ).mockRejectedValue(new Error("Read store unavailable") as never);
1281
+ tenant.add(recentDetection("alert-1"));
1282
+
1283
+ const result: SecurityEventConnectionRunResult = await poll();
1284
+
1285
+ expect(result.status).toBe("failed");
1286
+ expect(result.error).toBe("Read store unavailable");
1287
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
1288
+ expect(lastUpdate(persistence)).not.toHaveProperty("cursor");
1289
+ });
1290
+ });
1291
+
1292
+ /*
1293
+ * The duplicate lookup itself, under a real poll: SecurityEventDedupe runs
1294
+ * for real and only SecurityEventService.executeQuery is stubbed, so the
1295
+ * statement the poll sends ClickHouse is the one asserted.
1296
+ */
1297
+ describe("Google SecOps through the shared poller: duplicate lookup database contract", () => {
1298
+ let statements: Array<Statement>;
1299
+
1300
+ beforeEach(() => {
1301
+ statements = [];
1302
+ getJestSpyOn(SecurityEventDedupe, "findExistingEventUids").mockRestore();
1303
+ });
1304
+
1305
+ function answerLookups(
1306
+ rows: (statement: Statement) => Array<JSONObject>,
1307
+ ): void {
1308
+ getJestSpyOn(SecurityEventService, "executeQuery").mockImplementation(((
1309
+ statement: Statement,
1310
+ ): Promise<unknown> => {
1311
+ statements.push(statement);
1312
+ return Promise.resolve({
1313
+ json: async (): Promise<{ data: Array<JSONObject> }> => {
1314
+ return { data: rows(statement) };
1315
+ },
1316
+ });
1317
+ }) as never);
1318
+ }
1319
+
1320
+ test("binds untrusted identifiers, scopes the source to Google / Google SecOps and reads every replica without partial timeout results", async () => {
1321
+ const id: string = "id'); DROP TABLE SecurityEvent; --";
1322
+ // Stored twice on two replicas: still one identifier.
1323
+ answerLookups((): Array<JSONObject> => {
1324
+ return [{ eventUid: id }, { eventUid: id }];
1325
+ });
1326
+ tenant.add(recentDetection(id));
1327
+
1328
+ const result: SecurityEventConnectionRunResult = await poll();
1329
+
1330
+ expect(result.duplicateCount).toBe(1);
1331
+ expect(result.ingestedCount).toBe(0);
1332
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
1333
+ expect(statements).toHaveLength(1);
1334
+ expect(statements[0]!.query).toMatch(
1335
+ /SELECT DISTINCT eventUid FROM clusterAllReplicas/,
1336
+ );
1337
+ expect(statements[0]!.query).toMatch(/timeout_overflow_mode = 'throw'/);
1338
+ expect(statements[0]!.query).toMatch(/skip_unavailable_shards = 0/);
1339
+ expect(statements[0]!.query).not.toContain(id);
1340
+ const values: Array<unknown> = Object.values(statements[0]!.query_params);
1341
+ expect(values).toContain(PROJECT_ID.toString());
1342
+ expect(values).toContain("Google");
1343
+ expect(values).toContain("Google SecOps");
1344
+ expect(values).toContain("SecurityEventItemV1Local");
1345
+ expect(values).toContainEqual([id]);
1346
+ });
1347
+
1348
+ test("chunks the UID lookup of a large poll so no query carries unbounded parameters", async () => {
1349
+ answerLookups((): Array<JSONObject> => {
1350
+ return [];
1351
+ });
1352
+ for (let index: number = 0; index < 2501; index++) {
1353
+ tenant.add({
1354
+ id: `id-${index}`,
1355
+ createdMs: NOW.getTime() - 5 * MINUTE_MS + index * 100,
1356
+ // Detected long ago, so only the created-time search returns them.
1357
+ detectionMs: NOW.getTime() - 30 * DAY_MS,
1358
+ });
1359
+ }
1360
+
1361
+ const result: SecurityEventConnectionRunResult = await poll();
1362
+
1363
+ expect(tenant.requestsTo("search")).toHaveLength(3);
1364
+ expect(result.fetchedCount).toBe(2501);
1365
+ expect(result.ingestedCount).toBe(2501);
1366
+ expect(
1367
+ statements.map((statement: Statement): number => {
1368
+ return (
1369
+ Object.values(statement.query_params).find(
1370
+ Array.isArray,
1371
+ ) as Array<string>
1372
+ ).length;
1373
+ }),
1374
+ ).toEqual([1000, 1000, 501]);
1375
+ });
1376
+
1377
+ test("an unavailable replica fails the poll instead of importing possible duplicates", async () => {
1378
+ getJestSpyOn(SecurityEventService, "executeQuery").mockRejectedValue(
1379
+ new Error("Replica unavailable") as never,
1380
+ );
1381
+ tenant.add(recentDetection("alert-1"));
1382
+
1383
+ const result: SecurityEventConnectionRunResult = await poll();
1384
+
1385
+ expect(result.status).toBe("failed");
1386
+ expect(result.error).toContain("Replica unavailable");
1387
+ expect(SecurityEventService.insertJsonRows).not.toHaveBeenCalled();
1388
+ expect(lastUpdate(persistence)).not.toHaveProperty("cursor");
1389
+ });
1390
+ });