@oneuptime/common 12.0.32 → 12.0.34

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 (1191) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/AnalyticsModels/Span.ts +14 -0
  4. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  5. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  6. package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
  7. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  8. package/Models/DatabaseModels/Index.ts +10 -0
  9. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  10. package/Models/DatabaseModels/Monitor.ts +76 -0
  11. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  12. package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
  13. package/Models/DatabaseModels/NetworkDevice.ts +176 -1
  14. package/Models/DatabaseModels/NetworkSite.ts +201 -2
  15. package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
  16. package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
  17. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  18. package/Models/DatabaseModels/RumApplication.ts +6 -6
  19. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  20. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  21. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  22. package/Models/DatabaseModels/TeamMember.ts +0 -9
  23. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  24. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  25. package/Models/DatabaseModels/TelemetryException.ts +119 -0
  26. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  27. package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
  28. package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
  29. package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
  30. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  31. package/Scripts/benchmark-fanin-capacity.js +181 -0
  32. package/Server/API/EnterpriseLicenseAPI.ts +391 -64
  33. package/Server/API/LlmProviderAPI.ts +137 -22
  34. package/Server/API/TelemetryAPI.ts +1284 -164
  35. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  36. package/Server/API/UserTelegramAPI.ts +48 -4
  37. package/Server/EnvironmentConfig.ts +49 -2
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  49. package/Server/Infrastructure/QueueWorker.ts +59 -23
  50. package/Server/Infrastructure/Semaphore.ts +2 -0
  51. package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
  52. package/Server/Middleware/ProjectAuthorization.ts +11 -0
  53. package/Server/Middleware/SCIMAuthorization.ts +12 -0
  54. package/Server/Middleware/TelemetryIngest.ts +464 -7
  55. package/Server/Services/AIBillingService.ts +101 -27
  56. package/Server/Services/AccessTokenService.ts +1 -0
  57. package/Server/Services/AlertCustomFieldService.ts +98 -0
  58. package/Server/Services/AlertService.ts +37 -0
  59. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  60. package/Server/Services/CustomFieldMappingService.ts +879 -0
  61. package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
  62. package/Server/Services/EnterpriseLicenseService.ts +55 -0
  63. package/Server/Services/GlobalConfigService.ts +194 -0
  64. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  65. package/Server/Services/IncidentService.ts +35 -0
  66. package/Server/Services/Index.ts +10 -0
  67. package/Server/Services/MetricService.ts +194 -0
  68. package/Server/Services/MonitorService.ts +175 -21
  69. package/Server/Services/MonitorStatusTimelineService.ts +150 -8
  70. package/Server/Services/MonitorTemplateService.ts +217 -1
  71. package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
  72. package/Server/Services/NetworkAlertPolicyService.ts +944 -0
  73. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +87 -35
  74. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
  75. package/Server/Services/NetworkDeviceService.ts +1032 -73
  76. package/Server/Services/NetworkSiteService.ts +1502 -129
  77. package/Server/Services/NetworkSiteTypeService.ts +1216 -0
  78. package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
  79. package/Server/Services/NotificationService.ts +118 -28
  80. package/Server/Services/ProjectService.ts +127 -48
  81. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  82. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  83. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  84. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  85. package/Server/Services/StatusPagePrivateUserService.ts +103 -3
  86. package/Server/Services/TeamMemberService.ts +78 -0
  87. package/Server/Services/TeamPermissionService.ts +235 -3
  88. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  89. package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
  90. package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
  91. package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
  92. package/Server/Services/UserNotificationSettingService.ts +90 -25
  93. package/Server/Services/UserService.ts +95 -0
  94. package/Server/Services/UserTelegramService.ts +326 -5
  95. package/Server/Types/Database/QueryHelper.ts +4 -2
  96. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
  97. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
  98. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
  99. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
  100. package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
  101. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  102. package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
  103. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  104. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  105. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  106. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  107. package/Server/Utils/DataSource/HttpFetch.ts +9 -2
  108. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +131 -0
  109. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +925 -0
  110. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
  111. package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
  112. package/Server/Utils/FrontendEnvironment.ts +40 -0
  113. package/Server/Utils/LLM/LLMService.ts +78 -0
  114. package/Server/Utils/LogRedaction.ts +28 -0
  115. package/Server/Utils/Logger.ts +90 -1
  116. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
  117. package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
  118. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
  119. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  120. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
  121. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  122. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  123. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +159 -15
  124. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
  125. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  126. package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
  127. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +72 -0
  128. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
  129. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
  130. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
  131. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
  132. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  133. package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
  134. package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
  135. package/Server/Utils/OutboundUserAgent.ts +152 -0
  136. package/Server/Utils/SSRFProtection.ts +217 -10
  137. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  138. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  139. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  140. package/Server/Utils/StartServer.ts +53 -36
  141. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  142. package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
  143. package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
  144. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  145. package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
  146. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  147. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  148. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  149. package/Server/Utils/Telemetry.ts +198 -51
  150. package/Server/Utils/VM/VMAPI.ts +1 -0
  151. package/Server/Utils/VM/VMRunner.ts +975 -95
  152. package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
  153. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  154. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
  155. package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
  156. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
  157. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  158. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
  159. package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
  160. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +486 -9
  161. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
  162. package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
  163. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
  164. package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
  165. package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
  166. package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
  167. package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
  168. package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
  169. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
  170. package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
  171. package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
  172. package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
  173. package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
  174. package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
  175. package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
  176. package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
  177. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
  178. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
  179. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  180. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
  181. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  182. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  183. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  184. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  185. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  186. package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
  187. package/Tests/ResponsiveVisibility.test.ts +115 -0
  188. package/Tests/ResponsiveVisibility.ts +183 -0
  189. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
  190. package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
  191. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  192. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  193. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  194. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  195. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
  196. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  197. package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
  198. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
  199. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  200. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
  201. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  202. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  203. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  204. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  205. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  206. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
  207. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  208. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  209. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  210. package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
  211. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  212. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  213. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  214. package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
  215. package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
  216. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  217. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  218. package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
  219. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
  220. package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
  221. package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
  222. package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
  223. package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
  224. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +273 -5
  225. package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
  226. package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
  227. package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
  228. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
  229. package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
  230. package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
  231. package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
  232. package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
  233. package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
  234. package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
  235. package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
  236. package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
  237. package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
  238. package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
  239. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  240. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  241. package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
  242. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  243. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  244. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  245. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  246. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  247. package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
  248. package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
  249. package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
  250. package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
  251. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +997 -0
  252. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +110 -1
  253. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  254. package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
  255. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
  256. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
  257. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
  258. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
  259. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
  260. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  261. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  262. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  263. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  264. package/Tests/Server/Utils/Captcha.test.ts +422 -0
  265. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  266. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  267. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
  268. package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
  269. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  270. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
  271. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
  272. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  273. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
  274. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +828 -0
  275. package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
  276. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  277. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  278. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  279. package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
  280. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
  281. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
  282. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  283. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
  284. package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
  285. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
  286. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
  287. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
  288. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  289. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
  290. package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
  291. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
  292. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
  293. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  294. package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
  295. package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
  296. package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
  297. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  298. package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
  299. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  300. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  301. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  302. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  303. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  304. package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
  305. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  306. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  307. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  308. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  309. package/Tests/Server/Utils/Telemetry.test.ts +456 -66
  310. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  311. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  312. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  313. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  314. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  315. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  316. package/Tests/Types/JSONFunctions.test.ts +260 -0
  317. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  318. package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
  319. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  320. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  321. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  322. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  323. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  324. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  325. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  326. package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
  327. package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
  328. package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
  329. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
  330. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
  331. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  332. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  333. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  334. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  335. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  336. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  337. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  338. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  339. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  340. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  341. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  342. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  343. package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
  344. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
  345. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
  346. package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
  347. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  348. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  349. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  350. package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
  351. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  352. package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
  353. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  354. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  355. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  356. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  357. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  358. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  359. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  360. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  361. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  362. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  363. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  364. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  365. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  366. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +43 -12
  367. package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
  368. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  369. package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
  370. package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
  371. package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
  372. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  373. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  374. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  375. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  376. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  377. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  378. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  379. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  380. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  381. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  382. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  383. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  384. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  385. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  386. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  387. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  388. package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
  389. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  390. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  391. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  392. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  393. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  394. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  395. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  396. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  397. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  398. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  399. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  400. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  401. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  402. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  403. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  404. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  405. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  406. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  407. package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
  408. package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
  409. package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
  410. package/Tests/Utils/API.test.ts +308 -0
  411. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
  412. package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
  413. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
  414. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  415. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
  416. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  417. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
  418. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
  419. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
  420. package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
  421. package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
  422. package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
  423. package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
  424. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
  425. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
  426. package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
  427. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
  428. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  429. package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
  430. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
  431. package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
  432. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  433. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  434. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  435. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  436. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
  437. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  438. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  439. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  440. package/Types/AI/ExceptionAIClassification.ts +10 -24
  441. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  442. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  443. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  444. package/Types/Email/EmailTemplateType.ts +2 -0
  445. package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
  446. package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
  447. package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
  448. package/Types/Exception/ApiException.ts +10 -0
  449. package/Types/Exception/BadDataException.ts +11 -0
  450. package/Types/Exception/BadRequestException.ts +11 -0
  451. package/Types/Exception/Exception.ts +65 -0
  452. package/Types/Exception/ForbiddenException.ts +10 -0
  453. package/Types/Exception/NotAuthenticatedException.ts +10 -0
  454. package/Types/Exception/NotAuthorizedException.ts +10 -0
  455. package/Types/Exception/NotFoundException.ts +11 -0
  456. package/Types/Exception/PayloadTooLargeException.ts +11 -0
  457. package/Types/Exception/PaymentRequiredException.ts +10 -0
  458. package/Types/Exception/ServiceUnavailableException.ts +10 -0
  459. package/Types/Exception/SsoAuthorizationException.ts +10 -0
  460. package/Types/Exception/TenantNotFoundException.ts +11 -0
  461. package/Types/Exception/TimeoutException.ts +10 -0
  462. package/Types/Exception/TooManyRequestsException.ts +10 -0
  463. package/Types/Exception/UnableToReachServer.ts +10 -0
  464. package/Types/Exception/WebsiteRequestException.ts +10 -0
  465. package/Types/Icon/IconProp.ts +1 -0
  466. package/Types/JSONFunctions.ts +189 -43
  467. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  468. package/Types/Monitor/CriteriaFilter.ts +60 -2
  469. package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
  470. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
  471. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  472. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  473. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  474. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  475. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  476. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  477. package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
  478. package/Types/Monitor/MonitorMetricType.ts +71 -0
  479. package/Types/Monitor/MonitorStep.ts +76 -0
  480. package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
  481. package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
  482. package/Types/Monitor/MonitorType.ts +47 -1
  483. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  484. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  485. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  486. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  487. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  488. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  489. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  490. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  491. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  492. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
  493. package/Types/Monitor/SqlConnectionConfig.ts +31 -0
  494. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  495. package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
  496. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
  497. package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
  498. package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
  499. package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
  500. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  501. package/Types/Permission.ts +90 -0
  502. package/Types/Probe/ProbeMonitorResponse.ts +16 -0
  503. package/Types/Rum/SessionReplay.ts +209 -0
  504. package/Types/Rum/SessionReplayApi.ts +722 -0
  505. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  506. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  507. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  508. package/Types/Rum/SessionReplayHealth.ts +238 -0
  509. package/Types/Telemetry/ErrorClass.ts +274 -0
  510. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  511. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  512. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  513. package/Types/Telemetry/UnitOfWork.ts +59 -0
  514. package/Types/WebsiteRequest.ts +85 -3
  515. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  516. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  517. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  518. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  519. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  520. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  521. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  522. package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
  523. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
  524. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  525. package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
  526. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  527. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  528. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  529. package/UI/Components/Header/Header.tsx +25 -9
  530. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  531. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  532. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  533. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  534. package/UI/Components/Icon/Icon.tsx +11 -0
  535. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  536. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  537. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  538. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  539. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  540. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  541. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  542. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  543. package/UI/Components/Modal/Modal.tsx +2 -8
  544. package/UI/Components/ModelTable/Column.ts +15 -0
  545. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  546. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  547. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  548. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  549. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +88 -0
  550. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
  551. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
  552. package/UI/Components/SideMenu/SideMenu.tsx +123 -5
  553. package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
  554. package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
  555. package/UI/Components/SideOver/SideOver.tsx +21 -20
  556. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  557. package/UI/Components/Table/CellClassName.ts +81 -0
  558. package/UI/Components/Table/TableRow.tsx +20 -14
  559. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  560. package/UI/Components/Table/Types/Column.ts +36 -0
  561. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  562. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  563. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  564. package/UI/Components/Workflow/Workflow.tsx +47 -18
  565. package/UI/Config.ts +15 -33
  566. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  567. package/UI/Utils/PageScrollLock.ts +79 -3
  568. package/UI/Utils/PermissionGate.ts +61 -0
  569. package/UI/Utils/SensitiveUrlToken.ts +112 -0
  570. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  571. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  572. package/UI/Utils/TestLLMProvider.ts +11 -0
  573. package/Utils/API.ts +129 -3
  574. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
  575. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
  576. package/Utils/HTTPResponseBodyReader.ts +221 -0
  577. package/Utils/Monitor/MonitorMetricType.ts +153 -1
  578. package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
  579. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
  580. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
  581. package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
  582. package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
  583. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
  584. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
  585. package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
  586. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  587. package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
  588. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
  589. package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
  590. package/Utils/Rum/ChunkMath.ts +106 -0
  591. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  592. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  593. package/Utils/Schema/ModelSchema.ts +1 -0
  594. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  595. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  596. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  597. package/Utils/ValueFormatter.ts +35 -1
  598. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  599. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  600. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  601. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  602. package/build/dist/Models/AnalyticsModels/Span.js +14 -0
  603. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  604. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  605. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  606. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  607. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  608. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
  609. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  610. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  611. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  612. package/build/dist/Models/DatabaseModels/Index.js +10 -0
  613. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  614. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  615. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  616. package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
  617. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  618. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  619. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  620. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
  621. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
  622. package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
  623. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  624. package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
  625. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  626. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
  627. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
  628. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
  629. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
  630. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  631. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  632. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  633. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  634. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  635. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  636. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  637. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  638. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  639. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  640. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  641. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  642. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  643. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  644. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  645. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  646. package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
  647. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  648. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  649. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  650. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
  651. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
  652. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
  653. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
  654. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
  655. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
  656. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  657. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  658. package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
  659. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  660. package/build/dist/Server/API/LlmProviderAPI.js +108 -13
  661. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  662. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  663. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  664. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  665. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  666. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  667. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  668. package/build/dist/Server/EnvironmentConfig.js +41 -2
  669. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  670. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
  671. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
  672. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
  673. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
  674. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
  675. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
  676. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
  677. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
  678. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
  679. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
  680. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
  681. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
  682. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  683. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  684. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  685. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  686. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  687. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  688. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  689. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  690. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  691. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  692. package/build/dist/Server/Infrastructure/QueueWorker.js +52 -12
  693. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  694. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  695. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  696. package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
  697. package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
  698. package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
  699. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  700. package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
  701. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
  702. package/build/dist/Server/Middleware/TelemetryIngest.js +326 -8
  703. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  704. package/build/dist/Server/Services/AIBillingService.js +70 -16
  705. package/build/dist/Server/Services/AIBillingService.js.map +1 -1
  706. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  707. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  708. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  709. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  710. package/build/dist/Server/Services/AlertService.js +34 -0
  711. package/build/dist/Server/Services/AlertService.js.map +1 -1
  712. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  713. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  714. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  715. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  716. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
  717. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
  718. package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
  719. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  720. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  721. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  722. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  723. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  724. package/build/dist/Server/Services/IncidentService.js +32 -0
  725. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  726. package/build/dist/Server/Services/Index.js +10 -0
  727. package/build/dist/Server/Services/Index.js.map +1 -1
  728. package/build/dist/Server/Services/MetricService.js +163 -0
  729. package/build/dist/Server/Services/MetricService.js.map +1 -1
  730. package/build/dist/Server/Services/MonitorService.js +148 -21
  731. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  732. package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
  733. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  734. package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
  735. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  736. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
  737. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
  738. package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
  739. package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
  740. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +89 -36
  741. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  742. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
  743. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  744. package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
  745. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  746. package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
  747. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  748. package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
  749. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
  750. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
  751. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
  752. package/build/dist/Server/Services/NotificationService.js +80 -17
  753. package/build/dist/Server/Services/NotificationService.js.map +1 -1
  754. package/build/dist/Server/Services/ProjectService.js +88 -30
  755. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  756. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  757. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  758. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  759. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  760. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  761. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  762. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  763. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  764. package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
  765. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  766. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  767. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  768. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  769. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  770. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  771. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  772. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
  773. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
  774. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
  775. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
  776. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
  777. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
  778. package/build/dist/Server/Services/UserNotificationSettingService.js +66 -20
  779. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  780. package/build/dist/Server/Services/UserService.js +90 -0
  781. package/build/dist/Server/Services/UserService.js.map +1 -1
  782. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  783. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  784. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  785. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  786. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
  787. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  788. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
  789. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  790. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
  791. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  792. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
  793. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
  794. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
  795. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  796. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  797. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  798. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
  799. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
  800. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  801. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  802. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  803. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  804. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  805. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  806. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  807. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  808. package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
  809. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  810. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +124 -0
  811. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
  812. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +733 -0
  813. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
  814. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
  815. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
  816. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
  817. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
  818. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  819. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  820. package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
  821. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  822. package/build/dist/Server/Utils/LogRedaction.js +28 -0
  823. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  824. package/build/dist/Server/Utils/Logger.js +73 -1
  825. package/build/dist/Server/Utils/Logger.js.map +1 -1
  826. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
  827. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  828. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
  829. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
  830. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  831. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  832. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  833. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  834. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
  835. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  836. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  837. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  838. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  839. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  840. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +125 -13
  841. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  842. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
  843. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  844. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  845. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  846. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  847. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  848. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +54 -0
  849. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  850. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
  851. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  852. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
  853. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  854. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
  855. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  856. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
  857. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  858. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  859. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  860. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
  861. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
  862. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
  863. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
  864. package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
  865. package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
  866. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  867. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  868. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  869. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  870. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  871. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  872. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  873. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  874. package/build/dist/Server/Utils/StartServer.js +41 -28
  875. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  876. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  877. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  878. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
  879. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  880. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
  881. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
  882. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  883. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  884. package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
  885. package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
  886. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  887. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  888. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  889. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  890. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  891. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  892. package/build/dist/Server/Utils/Telemetry.js +162 -46
  893. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  894. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  895. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  896. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  897. package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
  898. package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
  899. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  900. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  901. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  902. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  903. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  904. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  905. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  906. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  907. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
  908. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
  909. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
  910. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
  911. package/build/dist/Types/Exception/ApiException.js +9 -0
  912. package/build/dist/Types/Exception/ApiException.js.map +1 -1
  913. package/build/dist/Types/Exception/BadDataException.js +10 -0
  914. package/build/dist/Types/Exception/BadDataException.js.map +1 -1
  915. package/build/dist/Types/Exception/BadRequestException.js +10 -0
  916. package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
  917. package/build/dist/Types/Exception/Exception.js +56 -0
  918. package/build/dist/Types/Exception/Exception.js.map +1 -1
  919. package/build/dist/Types/Exception/ForbiddenException.js +9 -0
  920. package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
  921. package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
  922. package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
  923. package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
  924. package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
  925. package/build/dist/Types/Exception/NotFoundException.js +10 -0
  926. package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
  927. package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
  928. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
  929. package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
  930. package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
  931. package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
  932. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
  933. package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
  934. package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
  935. package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
  936. package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
  937. package/build/dist/Types/Exception/TimeoutException.js +9 -0
  938. package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
  939. package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
  940. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
  941. package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
  942. package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
  943. package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
  944. package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
  945. package/build/dist/Types/Icon/IconProp.js +1 -0
  946. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  947. package/build/dist/Types/JSONFunctions.js +118 -37
  948. package/build/dist/Types/JSONFunctions.js.map +1 -1
  949. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  950. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  951. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
  952. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  953. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
  954. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
  955. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
  956. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
  957. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  958. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  959. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  960. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  961. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  962. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  963. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  964. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  965. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  966. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  967. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  968. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  969. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
  970. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  971. package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
  972. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  973. package/build/dist/Types/Monitor/MonitorStep.js +54 -0
  974. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  975. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
  976. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
  977. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  978. package/build/dist/Types/Monitor/MonitorType.js +45 -1
  979. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  980. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  981. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  982. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  983. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  984. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  985. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  986. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  987. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  988. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  989. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  990. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  991. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  992. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  993. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  994. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  995. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  996. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  997. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  998. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
  999. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  1000. package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
  1001. package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
  1002. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  1003. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  1004. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
  1005. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
  1006. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
  1007. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
  1008. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
  1009. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
  1010. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
  1011. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
  1012. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
  1013. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
  1014. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  1015. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  1016. package/build/dist/Types/Permission.js +80 -0
  1017. package/build/dist/Types/Permission.js.map +1 -1
  1018. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  1019. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  1020. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  1021. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  1022. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  1023. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  1024. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  1025. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  1026. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  1027. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  1028. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  1029. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  1030. package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
  1031. package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
  1032. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  1033. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  1034. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  1035. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  1036. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  1037. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  1038. package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
  1039. package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
  1040. package/build/dist/Types/WebsiteRequest.js +55 -3
  1041. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  1042. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  1043. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  1044. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  1045. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  1046. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  1047. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  1048. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  1049. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  1050. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  1051. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  1052. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  1053. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  1054. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  1055. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
  1056. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  1057. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
  1058. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  1059. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  1060. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  1061. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
  1062. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  1063. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  1064. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  1065. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  1066. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  1067. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  1068. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  1069. package/build/dist/UI/Components/Header/Header.js +2 -3
  1070. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  1071. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  1072. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  1073. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  1074. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  1075. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  1076. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  1077. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  1078. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  1079. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  1080. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  1081. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  1082. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  1083. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  1084. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  1085. package/build/dist/UI/Components/Modal/Modal.js +2 -7
  1086. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  1087. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  1088. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  1089. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  1090. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  1091. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  1092. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  1093. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  1094. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  1095. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +77 -0
  1096. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  1097. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
  1098. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  1099. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
  1100. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  1101. package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
  1102. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  1103. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
  1104. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  1105. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
  1106. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  1107. package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
  1108. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  1109. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  1110. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  1111. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  1112. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  1113. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  1114. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  1115. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  1116. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  1117. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  1118. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  1119. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  1120. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  1121. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  1122. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  1123. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  1124. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  1125. package/build/dist/UI/Config.js +10 -20
  1126. package/build/dist/UI/Config.js.map +1 -1
  1127. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  1128. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  1129. package/build/dist/UI/Utils/PageScrollLock.js +31 -3
  1130. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
  1131. package/build/dist/UI/Utils/PermissionGate.js +42 -1
  1132. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  1133. package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
  1134. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
  1135. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  1136. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  1137. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  1138. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  1139. package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
  1140. package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
  1141. package/build/dist/Utils/API.js +67 -5
  1142. package/build/dist/Utils/API.js.map +1 -1
  1143. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
  1144. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
  1145. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
  1146. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  1147. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  1148. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  1149. package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
  1150. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  1151. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
  1152. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  1153. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
  1154. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
  1155. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
  1156. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  1157. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
  1158. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
  1159. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
  1160. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
  1161. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
  1162. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  1163. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
  1164. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  1165. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
  1166. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
  1167. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  1168. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  1169. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
  1170. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
  1171. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
  1172. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  1173. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
  1174. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
  1175. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  1176. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  1177. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  1178. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  1179. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  1180. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  1181. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  1182. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  1183. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  1184. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  1185. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  1186. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  1187. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  1188. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  1189. package/build/dist/Utils/ValueFormatter.js +32 -1
  1190. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  1191. package/package.json +2 -2
@@ -1,17 +1,24 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import MonitorService from "./MonitorService";
3
+ import NetworkAlertPolicyEngineService, {
4
+ MAX_INLINE_RECONCILE_DEVICES,
5
+ } from "./NetworkAlertPolicyEngineService";
3
6
  import NetworkDeviceLabelRuleEngineService from "./NetworkDeviceLabelRuleEngineService";
4
7
  import NetworkDeviceOwnerRuleEngineService from "./NetworkDeviceOwnerRuleEngineService";
5
8
  import NetworkSiteAssignmentRuleService from "./NetworkSiteAssignmentRuleService";
6
9
  import NetworkSiteService from "./NetworkSiteService";
10
+ import NetworkSnmpCredentialProfileService from "./NetworkSnmpCredentialProfileService";
11
+ import ProbeService from "./ProbeService";
7
12
  import Model from "../../Models/DatabaseModels/NetworkDevice";
8
13
  import Monitor from "../../Models/DatabaseModels/Monitor";
9
14
  import NetworkSite from "../../Models/DatabaseModels/NetworkSite";
10
15
  import NetworkSiteAssignmentRule from "../../Models/DatabaseModels/NetworkSiteAssignmentRule";
16
+ import NetworkSnmpCredentialProfile from "../../Models/DatabaseModels/NetworkSnmpCredentialProfile";
11
17
  import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
12
18
  import CreateBy from "../Types/Database/CreateBy";
13
19
  import DeleteBy from "../Types/Database/DeleteBy";
14
20
  import UpdateBy from "../Types/Database/UpdateBy";
21
+ import PartialEntity from "../../Types/Database/PartialEntity";
15
22
  import Query from "../Types/Database/Query";
16
23
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
17
24
  import logger, { LogAttributes } from "../Utils/Logger";
@@ -137,8 +144,128 @@ function readOidTemplateIdFromData(
137
144
  );
138
145
  }
139
146
 
147
+ /*
148
+ * readConsistent for the same reason as the OID template above: the create
149
+ * and update guards validate the id this returns, and TypeORM's precedence
150
+ * between `monitorId` and `monitor` is not a security boundary. A payload
151
+ * that writes both spellings with different ids would have one of them
152
+ * validated and the other persisted, so the contradiction is refused
153
+ * instead of picked from.
154
+ */
140
155
  function readMonitorIdFromData(data: Record<string, unknown>): ObjectID | null {
141
- return RelationIdUtil.read(data, MONITOR_KEYS);
156
+ return RelationIdUtil.readConsistent(data, MONITOR_KEYS, "Monitor");
157
+ }
158
+
159
+ /*
160
+ * Both spellings of "the probe that polls this device", and of "the SNMP
161
+ * credentials it is walked with".
162
+ *
163
+ * These two are the tenancy boundary of device polling. The probe decides
164
+ * WHO reaches into the customer's network on this device's behalf, and the
165
+ * credential profile decides WHAT is put on the wire when it gets there —
166
+ * so a cross-project value in either is not a mislabelled row, it is one
167
+ * project's infrastructure being pointed at another's. Both are read
168
+ * through readConsistent for the reason the monitor reference above is: a
169
+ * payload writing the FK and the relation at different rows would otherwise
170
+ * have one validated and the other persisted.
171
+ */
172
+ const PROBE_KEYS: Array<string> = ["probeId", "probe"];
173
+ const PROFILE_KEYS: Array<string> = [
174
+ "snmpCredentialProfileId",
175
+ "snmpCredentialProfile",
176
+ ];
177
+
178
+ /*
179
+ * Both spellings of "what kind of thing this device is". A role is one of
180
+ * the three axes a Network Alert Policy's scope selects on, so a write to it
181
+ * can add a device to a policy or take it out of one.
182
+ */
183
+ const ROLE_KEYS: Array<string> = ["networkDeviceRoleId", "networkDeviceRole"];
184
+
185
+ /*
186
+ * Every write that can change which Network Alert Policies cover a device,
187
+ * or whether it may carry a policy monitor at all.
188
+ *
189
+ * The first three are the scope axes (site, role, labels); the last three
190
+ * are provisionability — an archived device, a monitor-backed device and a
191
+ * device with no probe each keep no policy monitors (see the engine).
192
+ *
193
+ * Writing any of them makes onUpdateSuccess reconcile, and reconciling needs
194
+ * each matched device's PROJECT, which only the pre-write snapshot carries
195
+ * for a root caller with no tenant in props. That is why these are named in
196
+ * onBeforeUpdate's early return as well: without them a bulk re-label would
197
+ * skip the snapshot and the success hook would have no project to reconcile
198
+ * against.
199
+ */
200
+ function isAlertPolicyRelevantWrite(dataKeys: Array<string>): boolean {
201
+ return (
202
+ isSiteWrite(dataKeys) ||
203
+ RelationIdUtil.isWritten(dataKeys, ROLE_KEYS) ||
204
+ dataKeys.includes("labels") ||
205
+ dataKeys.includes("isArchived") ||
206
+ dataKeys.includes("monitoringMethod") ||
207
+ RelationIdUtil.isWritten(dataKeys, PROBE_KEYS)
208
+ );
209
+ }
210
+
211
+ function readProbeIdFromData(data: Record<string, unknown>): ObjectID | null {
212
+ return RelationIdUtil.readConsistent(data, PROBE_KEYS, "Probe");
213
+ }
214
+
215
+ function readSnmpCredentialProfileIdFromData(
216
+ data: Record<string, unknown>,
217
+ ): ObjectID | null {
218
+ return RelationIdUtil.readConsistent(
219
+ data,
220
+ PROFILE_KEYS,
221
+ "SNMP Credential Profile",
222
+ );
223
+ }
224
+
225
+ /*
226
+ * The poll columns a probe's poll writes and nothing else ever should. On a
227
+ * device switched to monitor-backed they are residue — the last thing a
228
+ * probe found before it stopped asking — and left in place they keep
229
+ * describing a device nothing polls: DeviceReachabilityUtil's legacy branch
230
+ * judges a row with `lastSeenAt` and no `isReachable` by freshness, and the
231
+ * network summary's "degraded" query is `isReachable = true AND
232
+ * interfacesDown > 0`. The SNMP pair goes with them: a monitor-backed device
233
+ * has no walk, so `isSnmpReachable` and `lastSnmpSeenAt` can only ever be
234
+ * what the last walk left behind. Cleared on the Probe -> Monitor transition
235
+ * (onUpdateSuccess) and once on upgrade
236
+ * (BackfillMonitorBackedDeviceReachability), as a root write in both places:
237
+ * these columns are updatable by fewer roles than `monitoringMethod` is, so
238
+ * putting them on the caller's own payload would refuse a project member's
239
+ * legitimate switch.
240
+ */
241
+ function pollResidueReset(): PartialEntity<Model> {
242
+ return {
243
+ lastSeenAt: null,
244
+ lastPolledAt: null,
245
+ isReachable: null,
246
+ isSnmpReachable: null,
247
+ lastSnmpSeenAt: null,
248
+ interfacesUp: null,
249
+ interfacesDown: null,
250
+ };
251
+ }
252
+
253
+ /*
254
+ * What onBeforeUpdate hands onUpdateSuccess.
255
+ *
256
+ * `previousDevices` is the pre-write snapshot of every matched device, for
257
+ * the site and identity maintenance. `wasMonitorBackedByDeviceId` is only
258
+ * present on a write that carries `monitoringMethod`, and records which of
259
+ * those devices were monitor-backed BEFORE the write. By the time
260
+ * onUpdateSuccess runs only the NEW method is on the row, and the payload
261
+ * alone cannot tell a real Monitor -> Probe transition from the Settings form
262
+ * re-sending "Probe" on a Probe device — which it does on every save, and
263
+ * which used to wipe the stamp that device's Network Device monitor had put
264
+ * there.
265
+ */
266
+ interface DeviceUpdateCarryForward {
267
+ previousDevices: Array<Model>;
268
+ wasMonitorBackedByDeviceId?: Record<string, boolean>;
142
269
  }
143
270
 
144
271
  /*
@@ -687,6 +814,14 @@ export class Service extends DatabaseService<Model> {
687
814
  * first, then deletes their automatic monitors through MonitorService so
688
815
  * Monitor delete permissions, workspace cleanup, workflows, audit,
689
816
  * realtime, and billing hooks all run before the devices are removed.
817
+ *
818
+ * POLICY-OWNED MONITORS ARE HANDLED SEPARATELY, and deliberately so. A
819
+ * monitor a Network Alert Policy provisioned is system-managed — the API
820
+ * can neither set nor clear its `networkAlertPolicyId` — so nobody chose
821
+ * it individually and nobody should need monitor-delete permission on it
822
+ * individually to remove the device it describes. They are excluded from
823
+ * the caller-authorized preflight below and removed as root by the engine,
824
+ * once every device in the request has cleared that preflight.
690
825
  */
691
826
  @CaptureSpan()
692
827
  protected override async onBeforeDelete(
@@ -739,6 +874,13 @@ export class Service extends DatabaseService<Model> {
739
874
  const automaticMonitorQuery: Query<Monitor> = {
740
875
  projectId: device.projectId,
741
876
  autoProvisionedNetworkDeviceId: device.id,
877
+ /*
878
+ * Rule-provisioned and hand-made monitors only. A policy's monitors
879
+ * go through the engine as root (see the hook comment), so requiring
880
+ * the caller's permission on them here would refuse a device delete
881
+ * over rows the caller never chose to own.
882
+ */
883
+ networkAlertPolicyId: QueryHelper.isNull(),
742
884
  };
743
885
  const monitorDeleteProps: DatabaseCommonInteractionProps = {
744
886
  ...deleteBy.props,
@@ -783,6 +925,37 @@ export class Service extends DatabaseService<Model> {
783
925
  });
784
926
  }
785
927
 
928
+ /*
929
+ * Every device in the request has now proved the caller may delete its
930
+ * ordinary automatic monitors, so nothing after this point can throw for
931
+ * an authorization reason. That is the moment to remove the policy-owned
932
+ * monitors: doing it earlier would let a later device's failed preflight
933
+ * abort the request after a policy's monitors — and their incident
934
+ * history — were already gone from devices that then survived.
935
+ */
936
+ const devicesByProjectId: Map<string, Array<ObjectID>> = new Map<
937
+ string,
938
+ Array<ObjectID>
939
+ >();
940
+
941
+ for (const device of devices) {
942
+ if (!device.id || !device.projectId) {
943
+ continue;
944
+ }
945
+
946
+ const key: string = device.projectId.toString();
947
+ const deviceIds: Array<ObjectID> = devicesByProjectId.get(key) || [];
948
+ deviceIds.push(device.id);
949
+ devicesByProjectId.set(key, deviceIds);
950
+ }
951
+
952
+ for (const [projectIdString, deviceIds] of devicesByProjectId) {
953
+ await NetworkAlertPolicyEngineService.deletePolicyMonitorsForDevices({
954
+ projectId: new ObjectID(projectIdString),
955
+ deviceIds: deviceIds,
956
+ });
957
+ }
958
+
786
959
  for (const cleanupPlan of cleanupPlans) {
787
960
  /*
788
961
  * LIMIT_MAX is a per-service-call cap, not a lifecycle cap. Always
@@ -913,6 +1086,136 @@ export class Service extends DatabaseService<Model> {
913
1086
  }
914
1087
  }
915
1088
 
1089
+ /*
1090
+ * The FK behind `probeId` only requires the Probe row to exist. Probe ids
1091
+ * reach the server from the browser — the device create form, the settings
1092
+ * page and the bulk "Set probe" action all post one — so without this
1093
+ * check a device can be pointed at another project's probe, and that probe
1094
+ * then claims it on its next poll: it reads the device's hostname and its
1095
+ * SNMP credentials, and reports status back into this project. That is a
1096
+ * cross-tenant read of both configuration and network position.
1097
+ *
1098
+ * A GLOBAL probe has no project and is attachable anywhere, so this
1099
+ * delegates to ProbeService rather than comparing projectIds — the same
1100
+ * predicate that decides which probes a monitor may use.
1101
+ *
1102
+ * `claimDevicesForPolling` re-checks the pairing in SQL as a backstop, for
1103
+ * rows written before this guard existed. Both halves are load-bearing:
1104
+ * this one gives the operator an error at the point of the mistake, the
1105
+ * other one makes a stale row unpollable rather than merely unwritable.
1106
+ */
1107
+ @CaptureSpan()
1108
+ private async assertProbeIsAttachableToProject(data: {
1109
+ probeId: ObjectID;
1110
+ projectId: ObjectID | undefined;
1111
+ }): Promise<void> {
1112
+ if (!data.projectId) {
1113
+ return;
1114
+ }
1115
+
1116
+ const isAttachable: boolean = await ProbeService.isProbeAttachableToProject(
1117
+ {
1118
+ probeId: data.probeId,
1119
+ projectId: data.projectId,
1120
+ },
1121
+ );
1122
+
1123
+ if (!isAttachable) {
1124
+ throw new BadDataException(
1125
+ "Probe not found or it does not belong to this project.",
1126
+ );
1127
+ }
1128
+ }
1129
+
1130
+ /*
1131
+ * Same hole as the probe, on the other half of the poll: a credential
1132
+ * profile is read LIVE at poll time
1133
+ * (NetworkDeviceHydrationUtil.resolveSnmpCredentials), so a device pointed
1134
+ * at another project's profile would be walked with that project's
1135
+ * community string or v3 credentials — put on the wire, inside this
1136
+ * project's network, by this project's probe.
1137
+ *
1138
+ * The resolver drops a mismatched reference as a backstop and pings the
1139
+ * device instead. This is the half that stops the reference being written
1140
+ * at all, and it is the half that tells the operator why.
1141
+ */
1142
+ @CaptureSpan()
1143
+ private async assertSnmpCredentialProfileBelongsToProject(data: {
1144
+ snmpCredentialProfileId: ObjectID;
1145
+ projectId: ObjectID | undefined;
1146
+ }): Promise<void> {
1147
+ if (!data.projectId) {
1148
+ return;
1149
+ }
1150
+
1151
+ const profile: NetworkSnmpCredentialProfile | null =
1152
+ await NetworkSnmpCredentialProfileService.findOneById({
1153
+ id: data.snmpCredentialProfileId,
1154
+ select: {
1155
+ _id: true,
1156
+ projectId: true,
1157
+ },
1158
+ props: {
1159
+ isRoot: true,
1160
+ },
1161
+ });
1162
+
1163
+ if (!profile) {
1164
+ throw new BadDataException("SNMP Credential Profile not found.");
1165
+ }
1166
+
1167
+ if (
1168
+ profile.projectId &&
1169
+ profile.projectId.toString() !== data.projectId.toString()
1170
+ ) {
1171
+ throw new BadDataException(
1172
+ "SNMP Credential Profile must belong to the same project.",
1173
+ );
1174
+ }
1175
+ }
1176
+
1177
+ /*
1178
+ * The site's default probe, resolved for a device that is landing in that
1179
+ * site without one of its own — this site's `probeId`, or the nearest
1180
+ * ancestor that has one.
1181
+ *
1182
+ * Returns null rather than throwing when the inherited probe is not
1183
+ * attachable to the device's project. A site row written before the
1184
+ * tenancy guards existed must not be able to fail an unrelated device
1185
+ * write; the honest outcome is that the device is created with NO probe
1186
+ * (it reads Pending, and the operator picks one) rather than silently
1187
+ * copying another project's probe onto it.
1188
+ */
1189
+ @CaptureSpan()
1190
+ private async resolveInheritedSiteProbeId(data: {
1191
+ siteId: ObjectID;
1192
+ projectIds: Array<ObjectID>;
1193
+ }): Promise<ObjectID | null> {
1194
+ const inheritedProbeId: ObjectID | null =
1195
+ await NetworkSiteService.resolveDefaultProbeIdForSite(data.siteId);
1196
+
1197
+ if (!inheritedProbeId) {
1198
+ return null;
1199
+ }
1200
+
1201
+ for (const projectId of data.projectIds) {
1202
+ const isAttachable: boolean =
1203
+ await ProbeService.isProbeAttachableToProject({
1204
+ probeId: inheritedProbeId,
1205
+ projectId: projectId,
1206
+ });
1207
+
1208
+ if (!isAttachable) {
1209
+ logger.error(
1210
+ `Network site ${data.siteId.toString()} names default probe ${inheritedProbeId.toString()}, which is not attachable to project ${projectId.toString()}. Not inheriting it; the device is left without a probe.`,
1211
+ );
1212
+ return null;
1213
+ }
1214
+ }
1215
+
1216
+ return inheritedProbeId;
1217
+ }
1218
+
916
1219
  /*
917
1220
  * onBeforeUpdate runs before DatabaseService permission-checks the query,
918
1221
  * so reading the raw client query as root would hand the hook rows from
@@ -952,6 +1255,42 @@ export class Service extends DatabaseService<Model> {
952
1255
  });
953
1256
  }
954
1257
 
1258
+ /*
1259
+ * DatabaseService stamps the tenant column AFTER this hook runs, so a
1260
+ * device created from the dashboard reaches here with `projectId` still
1261
+ * unset and only `props.tenantId` to go on. The guards below are the
1262
+ * tenancy boundary of polling, so they must not be skipped for the one
1263
+ * write shape every UI create takes.
1264
+ */
1265
+ const createProjectId: ObjectID | undefined =
1266
+ createBy.data.projectId ||
1267
+ createBy.data.project?.id ||
1268
+ createBy.props.tenantId ||
1269
+ undefined;
1270
+
1271
+ const createProbeId: ObjectID | null = readProbeIdFromData(
1272
+ createBy.data as unknown as Record<string, unknown>,
1273
+ );
1274
+
1275
+ if (createProbeId) {
1276
+ await this.assertProbeIsAttachableToProject({
1277
+ probeId: createProbeId,
1278
+ projectId: createProjectId,
1279
+ });
1280
+ }
1281
+
1282
+ const createSnmpCredentialProfileId: ObjectID | null =
1283
+ readSnmpCredentialProfileIdFromData(
1284
+ createBy.data as unknown as Record<string, unknown>,
1285
+ );
1286
+
1287
+ if (createSnmpCredentialProfileId) {
1288
+ await this.assertSnmpCredentialProfileBelongsToProject({
1289
+ snmpCredentialProfileId: createSnmpCredentialProfileId,
1290
+ projectId: createProjectId,
1291
+ });
1292
+ }
1293
+
955
1294
  const createOidTemplateId: ObjectID | null = readOidTemplateIdFromData(
956
1295
  createBy.data as unknown as Record<string, unknown>,
957
1296
  );
@@ -976,37 +1315,76 @@ export class Service extends DatabaseService<Model> {
976
1315
  );
977
1316
  }
978
1317
 
1318
+ const monitorId: ObjectID | null = readMonitorIdFromData(
1319
+ createBy.data as unknown as Record<string, unknown>,
1320
+ );
1321
+
1322
+ /*
1323
+ * The monitor is NOT required. Discovery import is why: a subnet sweep
1324
+ * finds ping-only hosts in bulk and there is no monitor to bind them to
1325
+ * yet. Such a device is still worth recording — it belongs to a site,
1326
+ * carries labels, and appears on the topology map — and its status reads
1327
+ * Pending, tagged "No monitor", which is exactly true until somebody
1328
+ * points a monitor at it.
1329
+ *
1330
+ * But any binding that IS supplied is tenant-checked, whatever the
1331
+ * monitoring method. This guard used to sit inside the monitor-backed
1332
+ * branch below, which left a Probe-method create (or one with the method
1333
+ * omitted) free to persist another project's monitor FK: the FK only
1334
+ * proves the Monitor row exists, a Probe device may legitimately carry a
1335
+ * monitorId (NetworkSiteService.onMonitorStatusChanged stamps from it),
1336
+ * and a nested select through the relation reads that monitor's
1337
+ * configuration. The update path runs the same check.
1338
+ */
1339
+ if (monitorId) {
1340
+ await this.assertMonitorBelongsToProject({
1341
+ monitorId: monitorId,
1342
+ projectId: createBy.data.projectId,
1343
+ });
1344
+ }
1345
+
979
1346
  if (
980
1347
  NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
981
1348
  createBy.data.monitoringMethod,
982
1349
  )
983
1350
  ) {
984
- const monitorId: ObjectID | null = readMonitorIdFromData(
985
- createBy.data as unknown as Record<string, unknown>,
986
- );
987
-
988
1351
  /*
989
- * The monitor is NOT required here, though the create form asks for
990
- * one. Discovery import is why: a subnet sweep finds ping-only hosts
991
- * in bulk and there is no monitor to bind them to yet. Such a device
992
- * is still worth recordingit belongs to a site, carries labels, and
993
- * appears on the topology map — and its status reads "pending", which
994
- * is exactly true until somebody points a monitor at it.
1352
+ * Not a preference: nothing polls a monitor-backed device its bound
1353
+ * monitor's status is its status so leaving polling on would queue
1354
+ * a poll whose verdict nothing may read. claimDevicesForPolling
1355
+ * refuses these rows toothis is the half that keeps the column
1356
+ * honest for anything reading it.
995
1357
  */
996
- if (monitorId) {
997
- await this.assertMonitorBelongsToProject({
998
- monitorId: monitorId,
999
- projectId: createBy.data.projectId,
1000
- });
1001
- }
1002
-
1358
+ createBy.data.isPollingEnabled = false;
1359
+ } else if (siteId && !createProbeId) {
1003
1360
  /*
1004
- * Not a preference: a monitor-backed device has no probe and no
1005
- * credentials, so leaving polling on would queue a walk that can only
1006
- * ever fail. claimDevicesForPolling refuses these rows too this is
1007
- * the half that keeps the column honest for anything reading it.
1361
+ * Site default probe, COPIED AT WRITE.
1362
+ *
1363
+ * This is what lets an operator register a device with a name and an
1364
+ * address and nothing else: the site (or the nearest ancestor site
1365
+ * that names one) supplies the probe, and the device polls from its
1366
+ * first cycle instead of sitting Pending until somebody notices the
1367
+ * empty field.
1368
+ *
1369
+ * Copied, not read through, and that distinction is the whole design.
1370
+ * Nothing re-reads the site later, so editing a site's default probe
1371
+ * decides where FUTURE devices poll from and never re-points a fleet
1372
+ * that is already polling — a read-through default would turn one
1373
+ * dropdown change into a silent migration of every device in the
1374
+ * subtree onto a probe that may not even reach them.
1375
+ *
1376
+ * A device that names its own probe keeps it: `createProbeId` above is
1377
+ * the caller's explicit choice and always wins.
1008
1378
  */
1009
- createBy.data.isPollingEnabled = false;
1379
+ const inheritedProbeId: ObjectID | null =
1380
+ await this.resolveInheritedSiteProbeId({
1381
+ siteId: siteId,
1382
+ projectIds: createProjectId ? [createProjectId] : [],
1383
+ });
1384
+
1385
+ if (inheritedProbeId) {
1386
+ createBy.data.probeId = inheritedProbeId;
1387
+ }
1010
1388
  }
1011
1389
 
1012
1390
  return { createBy, carryForward: null };
@@ -1086,8 +1464,8 @@ export class Service extends DatabaseService<Model> {
1086
1464
  /*
1087
1465
  * A device created monitor-backed adopts its monitor's CURRENT
1088
1466
  * status right away rather than waiting for that monitor's next
1089
- * status CHANGE. Skipped for SNMP devices, which are judged by
1090
- * their own walk.
1467
+ * status CHANGE. Skipped for Probe devices, which are judged by
1468
+ * their own poll.
1091
1469
  */
1092
1470
  if (
1093
1471
  NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
@@ -1100,6 +1478,21 @@ export class Service extends DatabaseService<Model> {
1100
1478
  });
1101
1479
  }
1102
1480
  })
1481
+ .then(async () => {
1482
+ /*
1483
+ * LAST, and that ordering is the whole point. A Network Alert
1484
+ * Policy can be scoped by site, by role and by LABEL, and the
1485
+ * label and site links above are what put those on a newly
1486
+ * imported device — a discovery import arrives with neither. Asking
1487
+ * the policy engine before they land would reconcile the device
1488
+ * against a scope it does not match yet, provision nothing, and
1489
+ * leave the device uncovered until the five-minute sweep.
1490
+ */
1491
+ await NetworkAlertPolicyEngineService.reconcileDevice({
1492
+ projectId: createdItem.projectId!,
1493
+ deviceId: createdItem.id!,
1494
+ });
1495
+ })
1103
1496
  .catch((error: Error) => {
1104
1497
  logger.error(
1105
1498
  `Error applying network device rules in NetworkDeviceService.onCreateSuccess: ${error}`,
@@ -1116,9 +1509,13 @@ export class Service extends DatabaseService<Model> {
1116
1509
  /*
1117
1510
  * Capture the previous state of every matched device when an update
1118
1511
  * touches siteId (so onUpdateSuccess can refresh the OLD site's rollup as
1119
- * well as the new one) or touches one of the columns site assignment rules
1512
+ * well as the new one), touches one of the columns site assignment rules
1120
1513
  * match on (so onUpdateSuccess can tell a real rename from the identical
1121
- * sysName the SNMP walk rewrites on every poll).
1514
+ * sysName the SNMP walk rewrites on every poll), or touches
1515
+ * monitoringMethod (so onUpdateSuccess can tell a real Monitor -> Probe
1516
+ * transition from a form re-sending the method the device already has).
1517
+ * The same read feeds the tenancy guards on the site, monitor and OID
1518
+ * template references.
1122
1519
  */
1123
1520
  @CaptureSpan()
1124
1521
  protected override async onBeforeUpdate(
@@ -1128,15 +1525,17 @@ export class Service extends DatabaseService<Model> {
1128
1525
 
1129
1526
  /*
1130
1527
  * Switching a device to monitor-backed turns polling off with it. The
1131
- * two are one decision, not two: a device with no probe and no
1132
- * credentials cannot be walked, so leaving the flag on would queue a
1133
- * walk per interval that can only fail and then paint the device down.
1528
+ * two are one decision, not two: a monitor-backed device's health is
1529
+ * its bound monitor's, so leaving the flag on would queue a poll per
1530
+ * interval whose verdict nothing may read. The way back is the mirror
1531
+ * image — onUpdateSuccess restores polling on a real Monitor -> Probe
1532
+ * transition, per device, once the write has committed.
1134
1533
  */
1135
1534
  const isMethodWrite: boolean = dataKeys.includes("monitoringMethod");
1136
1535
  /*
1137
1536
  * An update payload is a QueryDeepPartialEntity, so a column can hold a
1138
1537
  * raw value OR a SQL-expression function. Only a plain string is a
1139
- * method we can reason about; anything else falls through to the SNMP
1538
+ * method we can reason about; anything else falls through to the Probe
1140
1539
  * default, which changes nothing.
1141
1540
  */
1142
1541
  const writtenMethod: unknown = (
@@ -1148,6 +1547,16 @@ export class Service extends DatabaseService<Model> {
1148
1547
  NetworkDeviceMonitoringMethodUtil.isMonitorBacked(writtenMethod);
1149
1548
 
1150
1549
  if (becomesMonitorBacked) {
1550
+ /*
1551
+ * Only the polling flag is forced onto the payload, deliberately. The
1552
+ * poll residue the device carries over from its probe-polled days has to go
1553
+ * too, but the column-permission check runs on this payload AFTER the
1554
+ * hook, and those columns are updatable by fewer roles than
1555
+ * monitoringMethod is — so adding them here would turn a project
1556
+ * member's legitimate switch into a permission failure.
1557
+ * onUpdateSuccess clears them as root once the transition has
1558
+ * committed; see pollResidueReset.
1559
+ */
1151
1560
  updateBy.data.isPollingEnabled = false;
1152
1561
  }
1153
1562
 
@@ -1159,37 +1568,36 @@ export class Service extends DatabaseService<Model> {
1159
1568
  * nothing ever polled it. Only checked when the payload actually asks
1160
1569
  * for it, so the ordinary update path costs no extra query.
1161
1570
  */
1162
- if (
1571
+ const isPollingTurnOn: boolean =
1163
1572
  !becomesMonitorBacked &&
1164
1573
  dataKeys.includes("isPollingEnabled") &&
1165
- updateBy.data.isPollingEnabled === true
1166
- ) {
1167
- const targets: Array<Model> = await this.findBy({
1168
- query: this.scopeQueryToCallerTenant(updateBy.query, updateBy.props),
1169
- select: {
1170
- _id: true,
1171
- monitoringMethod: true,
1172
- },
1173
- limit: LIMIT_MAX,
1174
- skip: 0,
1175
- props: {
1176
- isRoot: true,
1177
- },
1178
- });
1574
+ updateBy.data.isPollingEnabled === true;
1179
1575
 
1180
- const isTargetMonitorBacked: boolean = targets.some((target: Model) => {
1181
- return NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
1182
- target.monitoringMethod,
1183
- );
1184
- });
1576
+ /*
1577
+ * Read — and, for conflicting spellings, refused — before the early
1578
+ * return below, so a payload that points `monitorId` and `monitor` at
1579
+ * different rows is rejected on every write shape rather than only on
1580
+ * the ones that happen to need the snapshot. Null means the write
1581
+ * unbinds the monitor, or does not mention it; neither needs a lookup.
1582
+ */
1583
+ const newMonitorId: ObjectID | null = readMonitorIdFromData(
1584
+ updateBy.data as unknown as Record<string, unknown>,
1585
+ );
1185
1586
 
1186
- // Unless the same write is moving it back to SNMP, which is allowed.
1187
- if (isTargetMonitorBacked && !(isMethodWrite && !becomesMonitorBacked)) {
1188
- throw new BadDataException(
1189
- "This device is monitor-backed, so there is nothing to poll it has no probe and no SNMP credentials. Switch its monitoring method to SNMP first.",
1190
- );
1191
- }
1192
- }
1587
+ /*
1588
+ * Read here, above the early return, for the same reason the monitor id
1589
+ * is: a payload that points `probeId` and `probe` (or the two credential
1590
+ * profile spellings) at different rows is a contradiction, and it is
1591
+ * refused on every write shape rather than only on the ones that happen
1592
+ * to need the snapshot below.
1593
+ */
1594
+ const newProbeId: ObjectID | null = readProbeIdFromData(
1595
+ updateBy.data as unknown as Record<string, unknown>,
1596
+ );
1597
+ const newSnmpCredentialProfileId: ObjectID | null =
1598
+ readSnmpCredentialProfileIdFromData(
1599
+ updateBy.data as unknown as Record<string, unknown>,
1600
+ );
1193
1601
 
1194
1602
  const isSiteChange: boolean = isSiteWrite(dataKeys);
1195
1603
  const isIdentityChange: boolean = SITE_RULE_IDENTITY_COLUMNS.some(
@@ -1218,12 +1626,51 @@ export class Service extends DatabaseService<Model> {
1218
1626
  OID_TEMPLATE_KEYS,
1219
1627
  );
1220
1628
  const isDeviceOidsChange: boolean = updateBy.data.snmpOids !== undefined;
1629
+ /*
1630
+ * The polling tenancy pair, named in the early return for exactly the
1631
+ * reason the OID template is: assigning a probe or a credential profile
1632
+ * changes neither site nor identity, so a guard placed below the return
1633
+ * would be dead code on the only writes it exists for — the settings
1634
+ * page's Monitoring section and the device-list bulk actions, which post
1635
+ * precisely these columns and nothing else.
1636
+ */
1637
+ const isProbeChange: boolean = RelationIdUtil.isWritten(
1638
+ dataKeys,
1639
+ PROBE_KEYS,
1640
+ );
1641
+ const isSnmpCredentialProfileChange: boolean = RelationIdUtil.isWritten(
1642
+ dataKeys,
1643
+ PROFILE_KEYS,
1644
+ );
1645
+
1646
+ /*
1647
+ * One snapshot read serves every guard and carry-forward below, and the
1648
+ * SNMP walk's per-poll column writes — the hot path through here — need
1649
+ * none of them. Binding a monitor is on the list for the same reason the
1650
+ * OID template is: it is exactly the write shape that changes neither
1651
+ * site nor identity, so a tenancy guard placed below a narrower return
1652
+ * would never run on the only write it exists for.
1653
+ */
1654
+ /*
1655
+ * The alert-policy axes ride the same return, and for the same reason
1656
+ * the OID template does: re-labelling a device or moving it to a role
1657
+ * changes neither its site nor its identity, so a snapshot taken below a
1658
+ * narrower return would be absent on exactly the writes onUpdateSuccess
1659
+ * needs it for. See isAlertPolicyRelevantWrite.
1660
+ */
1661
+ const isAlertPolicyChange: boolean = isAlertPolicyRelevantWrite(dataKeys);
1221
1662
 
1222
1663
  if (
1664
+ !isMethodWrite &&
1665
+ !isPollingTurnOn &&
1666
+ !newMonitorId &&
1223
1667
  !isSiteChange &&
1224
1668
  !isIdentityChange &&
1225
1669
  !isOidTemplateChange &&
1226
- !isDeviceOidsChange
1670
+ !isDeviceOidsChange &&
1671
+ !isProbeChange &&
1672
+ !isSnmpCredentialProfileChange &&
1673
+ !isAlertPolicyChange
1227
1674
  ) {
1228
1675
  return { updateBy, carryForward: null };
1229
1676
  }
@@ -1237,9 +1684,18 @@ export class Service extends DatabaseService<Model> {
1237
1684
  hostname: true,
1238
1685
  name: true,
1239
1686
  sysName: true,
1687
+ /*
1688
+ * Whether the device already has a probe. The site-default
1689
+ * inheritance below must never overwrite one, and this column is
1690
+ * the only way to tell "no probe yet" from "a probe the operator
1691
+ * chose" once the write has committed.
1692
+ */
1693
+ probeId: true,
1240
1694
  // Decide which OID budget applies below, and whether a link would truncate.
1241
1695
  oidTemplateId: true,
1242
1696
  snmpOids: true,
1697
+ // The polling guard and the method transition both need the OLD method.
1698
+ monitoringMethod: true,
1243
1699
  },
1244
1700
  limit: LIMIT_MAX,
1245
1701
  skip: 0,
@@ -1248,6 +1704,47 @@ export class Service extends DatabaseService<Model> {
1248
1704
  },
1249
1705
  });
1250
1706
 
1707
+ if (isPollingTurnOn) {
1708
+ const isTargetMonitorBacked: boolean = previousDevices.some(
1709
+ (target: Model) => {
1710
+ return NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
1711
+ target.monitoringMethod,
1712
+ );
1713
+ },
1714
+ );
1715
+
1716
+ // Unless the same write is moving it back to Probe, which is allowed.
1717
+ if (isTargetMonitorBacked && !(isMethodWrite && !becomesMonitorBacked)) {
1718
+ throw new BadDataException(
1719
+ "This device is monitor-backed, so there is nothing to poll — its bound monitor's status is its status. Switch its monitoring method to Probe first.",
1720
+ );
1721
+ }
1722
+ }
1723
+
1724
+ /*
1725
+ * Which of the matched devices were monitor-backed BEFORE this write.
1726
+ * Only recorded on a method write, because only a method write can be a
1727
+ * transition; see DeviceUpdateCarryForward for what onUpdateSuccess does
1728
+ * with it and why the payload alone is not enough.
1729
+ */
1730
+ let wasMonitorBackedByDeviceId: Record<string, boolean> | undefined =
1731
+ undefined;
1732
+
1733
+ if (isMethodWrite) {
1734
+ wasMonitorBackedByDeviceId = {};
1735
+
1736
+ for (const previousDevice of previousDevices) {
1737
+ if (!previousDevice.id) {
1738
+ continue;
1739
+ }
1740
+
1741
+ wasMonitorBackedByDeviceId[previousDevice.id.toString()] =
1742
+ NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
1743
+ previousDevice.monitoringMethod,
1744
+ );
1745
+ }
1746
+ }
1747
+
1251
1748
  const newSiteId: ObjectID | null = readSiteIdFromData(
1252
1749
  updateBy.data as unknown as Record<string, unknown>,
1253
1750
  );
@@ -1271,6 +1768,34 @@ export class Service extends DatabaseService<Model> {
1271
1768
  }
1272
1769
  }
1273
1770
 
1771
+ /*
1772
+ * The monitor guard on the UPDATE path. Until this existed only
1773
+ * onBeforeCreate checked the binding, so a device could be created
1774
+ * clean and then re-pointed at another project's monitor with a plain
1775
+ * update — and read that monitor's status through the device, since
1776
+ * refreshStampedMonitorStatus stamps whatever `monitorId` names. One
1777
+ * check per distinct project in the matched set, like the site guard
1778
+ * above. An unbind (null) has nothing to check.
1779
+ */
1780
+ if (newMonitorId) {
1781
+ const checkedMonitorProjectIds: Set<string> = new Set();
1782
+
1783
+ for (const previousDevice of previousDevices) {
1784
+ if (
1785
+ !previousDevice.projectId ||
1786
+ checkedMonitorProjectIds.has(previousDevice.projectId.toString())
1787
+ ) {
1788
+ continue;
1789
+ }
1790
+ checkedMonitorProjectIds.add(previousDevice.projectId.toString());
1791
+
1792
+ await this.assertMonitorBelongsToProject({
1793
+ monitorId: newMonitorId,
1794
+ projectId: previousDevice.projectId,
1795
+ });
1796
+ }
1797
+ }
1798
+
1274
1799
  const newOidTemplateId: ObjectID | null = readOidTemplateIdFromData(
1275
1800
  updateBy.data as unknown as Record<string, unknown>,
1276
1801
  );
@@ -1299,6 +1824,56 @@ export class Service extends DatabaseService<Model> {
1299
1824
  }
1300
1825
  }
1301
1826
 
1827
+ /*
1828
+ * The polling tenancy guards on the UPDATE path. A device created clean
1829
+ * and then re-pointed with a plain update is the same breach as one
1830
+ * created that way, so both hooks check both references. One check per
1831
+ * distinct project in the matched set, like the guards above — a single
1832
+ * updateBy can span projects when a root caller issues it, and the
1833
+ * payload names ONE probe and ONE profile for all of them.
1834
+ *
1835
+ * A clear (null) points at nothing and has nothing to check.
1836
+ */
1837
+ const distinctProjectIds: Array<ObjectID> = [];
1838
+ const seenProjectIds: Set<string> = new Set();
1839
+
1840
+ for (const previousDevice of previousDevices) {
1841
+ if (
1842
+ !previousDevice.projectId ||
1843
+ seenProjectIds.has(previousDevice.projectId.toString())
1844
+ ) {
1845
+ continue;
1846
+ }
1847
+ seenProjectIds.add(previousDevice.projectId.toString());
1848
+ distinctProjectIds.push(previousDevice.projectId);
1849
+ }
1850
+
1851
+ for (const projectId of distinctProjectIds) {
1852
+ if (newProbeId) {
1853
+ await this.assertProbeIsAttachableToProject({
1854
+ probeId: newProbeId,
1855
+ projectId: projectId,
1856
+ });
1857
+ }
1858
+
1859
+ if (newSnmpCredentialProfileId) {
1860
+ await this.assertSnmpCredentialProfileBelongsToProject({
1861
+ snmpCredentialProfileId: newSnmpCredentialProfileId,
1862
+ projectId: projectId,
1863
+ });
1864
+ }
1865
+ }
1866
+
1867
+ await this.applySiteDefaultProbeOnMove({
1868
+ updateBy: updateBy,
1869
+ previousDevices: previousDevices,
1870
+ distinctProjectIds: distinctProjectIds,
1871
+ newSiteId: newSiteId,
1872
+ isProbeChange: isProbeChange,
1873
+ isMethodWrite: isMethodWrite,
1874
+ becomesMonitorBacked: becomesMonitorBacked,
1875
+ });
1876
+
1302
1877
  /*
1303
1878
  * How many OIDs a device may carry of its own.
1304
1879
  *
@@ -1351,17 +1926,96 @@ export class Service extends DatabaseService<Model> {
1351
1926
  );
1352
1927
  }
1353
1928
 
1929
+ const carryForward: DeviceUpdateCarryForward = {
1930
+ previousDevices: previousDevices,
1931
+ };
1932
+
1933
+ if (wasMonitorBackedByDeviceId) {
1934
+ carryForward.wasMonitorBackedByDeviceId = wasMonitorBackedByDeviceId;
1935
+ }
1936
+
1354
1937
  return {
1355
1938
  updateBy,
1356
- carryForward: {
1357
- previousDevices: previousDevices,
1358
- },
1939
+ carryForward: carryForward,
1359
1940
  };
1360
1941
  }
1361
1942
 
1362
1943
  /*
1363
- * Re-derives one device's stamped `currentMonitorStatusId` from its
1364
- * binding, and refreshes its site chain if the stamp moved.
1944
+ * Site default probe on a MOVE: a device with no probe of its own that is
1945
+ * moved into a site inherits that site's default (or the nearest
1946
+ * ancestor's), copied onto this same write.
1947
+ *
1948
+ * The create path's twin, and the same copy-at-write rule: this runs only
1949
+ * because the payload moves the device, never because a site's default
1950
+ * changed. Editing a site's probe re-points nothing — the device-list bulk
1951
+ * "Set probe" action is the deliberate way to move a fleet.
1952
+ *
1953
+ * Three things stop it: the caller writing a probe of its own (their
1954
+ * choice wins, including an explicit clear), the device already having one
1955
+ * (a probe an operator chose must survive being filed under a site), and
1956
+ * the device being monitor-backed after this write (nothing polls it, so a
1957
+ * probe would be a lie on the row).
1958
+ *
1959
+ * "Already having one" is judged across the WHOLE matched set, because a
1960
+ * single payload writes one probeId to every row it matches: if any
1961
+ * matched device has a probe, inheriting would re-point it, so the
1962
+ * inheritance is skipped for the batch rather than applied to some of it.
1963
+ * The bulk path a user actually takes — "move these devices to this site"
1964
+ * — is overwhelmingly devices in the same state.
1965
+ */
1966
+ private async applySiteDefaultProbeOnMove(data: {
1967
+ updateBy: UpdateBy<Model>;
1968
+ previousDevices: Array<Model>;
1969
+ distinctProjectIds: Array<ObjectID>;
1970
+ newSiteId: ObjectID | null;
1971
+ isProbeChange: boolean;
1972
+ isMethodWrite: boolean;
1973
+ becomesMonitorBacked: boolean;
1974
+ }): Promise<void> {
1975
+ if (
1976
+ !data.newSiteId ||
1977
+ data.isProbeChange ||
1978
+ data.previousDevices.length === 0
1979
+ ) {
1980
+ return;
1981
+ }
1982
+
1983
+ for (const previousDevice of data.previousDevices) {
1984
+ if (previousDevice.probeId) {
1985
+ return;
1986
+ }
1987
+
1988
+ /*
1989
+ * The method AFTER this write: what the payload sets when it sets one,
1990
+ * otherwise what the row already says. A device that stays (or
1991
+ * becomes) monitor-backed is not polled by a probe at all.
1992
+ */
1993
+ const isMonitorBackedAfterWrite: boolean = data.isMethodWrite
1994
+ ? data.becomesMonitorBacked
1995
+ : NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
1996
+ previousDevice.monitoringMethod,
1997
+ );
1998
+
1999
+ if (isMonitorBackedAfterWrite) {
2000
+ return;
2001
+ }
2002
+ }
2003
+
2004
+ const inheritedProbeId: ObjectID | null =
2005
+ await this.resolveInheritedSiteProbeId({
2006
+ siteId: data.newSiteId,
2007
+ projectIds: data.distinctProjectIds,
2008
+ });
2009
+
2010
+ if (inheritedProbeId) {
2011
+ data.updateBy.data.probeId = inheritedProbeId;
2012
+ }
2013
+ }
2014
+
2015
+ /*
2016
+ * Re-derives one device's stamped `currentMonitorStatusId` — and, for a
2017
+ * monitor-backed device, its `isReachable` — from its binding, and
2018
+ * refreshes its site chain if either moved.
1365
2019
  *
1366
2020
  * The stamp is what every monitor-backed surface reads — the device list
1367
2021
  * pill, the site rollup, the topology node — and until this existed the
@@ -1373,14 +2027,33 @@ export class Service extends DatabaseService<Model> {
1373
2027
  * OneUptime/oneuptime#3392. Binding is itself an event that decides the
1374
2028
  * device's status, so it stamps here.
1375
2029
  *
2030
+ * `isReachable` rides along because the device list's summary tiles and
2031
+ * its Status facet count and filter in SQL, over that column alone — they
2032
+ * cannot evaluate the stamp's ladder per row — so a monitor-backed device
2033
+ * whose stamp said Operational still counted as "Pending" there. The
2034
+ * value written is `!MonitorStatus.isOfflineState`: the OFFLINE end of the
2035
+ * ladder, not the operational one, because that is exactly what
2036
+ * DeviceReachabilityUtil reads for the pill (a "Degraded" row is neither
2037
+ * operational nor offline, and reads as reachable on both). NULL when
2038
+ * nothing is bound or the monitor has no status, which is the honest
2039
+ * "Pending" the util renders for `undefined`. For a Probe device the poll
2040
+ * owns `isReachable`, and this method never touches it.
2041
+ *
1376
2042
  * `clearWhenNotMonitorBacked` is for the write that moves a device OFF
1377
2043
  * monitor-backed: the ping monitor's verdict must not outlive the binding
1378
2044
  * (DeviceHealthStateUtil lets a stamped status beat reachability, so a
1379
2045
  * stale one would poison the site rollup of a device that is now walked).
1380
2046
  * It is deliberately NOT set when a write only touches the monitor
1381
- * binding of an SNMP device, because an SNMP device's stamp comes from
1382
- * the Network Device monitor that watches it, and that binding lives in
1383
- * the monitor's step data rather than in this column.
2047
+ * binding of a Probe device, nor when a form re-sends "Probe" on a device
2048
+ * that already is one, because a Probe device's stamp comes from the
2049
+ * Network Device monitor that watches it, and that binding lives in the
2050
+ * monitor's step data rather than in this column. onBeforeUpdate records
2051
+ * the old method so onUpdateSuccess can tell the two apart.
2052
+ *
2053
+ * Idempotent: everything is re-derived from the binding, nothing from what
2054
+ * a previous call wrote, and nothing is written when the row already
2055
+ * agrees — which is what makes it safe from every save, from monitor
2056
+ * deletion, and from a backfill running twice concurrently.
1384
2057
  */
1385
2058
  @CaptureSpan()
1386
2059
  public async refreshStampedMonitorStatus(data: {
@@ -1396,6 +2069,10 @@ export class Service extends DatabaseService<Model> {
1396
2069
  monitoringMethod: true,
1397
2070
  monitorId: true,
1398
2071
  currentMonitorStatusId: true,
2072
+ isReachable: true,
2073
+ // Read only to decide whether the clear below has anything to clear.
2074
+ isSnmpReachable: true,
2075
+ lastSnmpSeenAt: true,
1399
2076
  },
1400
2077
  props: {
1401
2078
  isRoot: true,
@@ -1411,13 +2088,64 @@ export class Service extends DatabaseService<Model> {
1411
2088
  device.monitoringMethod,
1412
2089
  );
1413
2090
 
1414
- if (!isMonitorBacked && !data.clearWhenNotMonitorBacked) {
2091
+ if (!isMonitorBacked) {
2092
+ if (!data.clearWhenNotMonitorBacked) {
2093
+ return;
2094
+ }
2095
+
2096
+ /*
2097
+ * The device has just left monitor-backed. While it was monitor-backed
2098
+ * its `isReachable` could only ever be the bound monitor's mirror: the
2099
+ * poll's value was NULLed on the way in (pollResidueReset), and
2100
+ * NetworkInventoryUtil never writes it for a monitor-backed row. So the
2101
+ * mirror goes with the stamp — otherwise a device switched back to
2102
+ * Probe would read "Down — the last poll could not reach it" (or Up)
2103
+ * on every surface, from the verdict of a monitor that no longer
2104
+ * governs it, until a poll happens to land. NULL is the honest answer:
2105
+ * Pending until the first poll decides.
2106
+ *
2107
+ * The SNMP pair is cleared with them for the same reason: nothing
2108
+ * walked the device while it was monitor-backed, so anything on those
2109
+ * two columns predates the binding, and a device switched back to
2110
+ * Probe starts clean — its first poll decides whether SNMP answers.
2111
+ *
2112
+ * Nothing to clear means nothing to write — a null-over-null write
2113
+ * would still recompute the site chain for nothing.
2114
+ */
2115
+ const hasStamp: boolean = Boolean(device.currentMonitorStatusId);
2116
+ const hasMirroredReachability: boolean =
2117
+ typeof device.isReachable === "boolean";
2118
+ const hasSnmpResidue: boolean =
2119
+ typeof device.isSnmpReachable === "boolean" ||
2120
+ (device.lastSnmpSeenAt !== null && device.lastSnmpSeenAt !== undefined);
2121
+
2122
+ if (!hasStamp && !hasMirroredReachability && !hasSnmpResidue) {
2123
+ return;
2124
+ }
2125
+
2126
+ await this.updateColumnsByIdWithoutHooks({
2127
+ id: data.deviceId,
2128
+ data: {
2129
+ currentMonitorStatusId: null,
2130
+ isReachable: null,
2131
+ isSnmpReachable: null,
2132
+ lastSnmpSeenAt: null,
2133
+ },
2134
+ });
2135
+
2136
+ if (device.siteId) {
2137
+ await NetworkSiteService.recomputeRollupForSiteAndAncestors(
2138
+ device.siteId,
2139
+ );
2140
+ }
2141
+
1415
2142
  return;
1416
2143
  }
1417
2144
 
1418
2145
  let monitorStatusId: ObjectID | null = null;
2146
+ let nextReachable: boolean | null = null;
1419
2147
 
1420
- if (isMonitorBacked && device.monitorId) {
2148
+ if (device.monitorId) {
1421
2149
  /*
1422
2150
  * Scoped to the device's project on the read as well as on the write
1423
2151
  * path in onBeforeCreate/onBeforeUpdate: a monitor from another
@@ -1431,6 +2159,9 @@ export class Service extends DatabaseService<Model> {
1431
2159
  select: {
1432
2160
  _id: true,
1433
2161
  currentMonitorStatusId: true,
2162
+ currentMonitorStatus: {
2163
+ isOfflineState: true,
2164
+ },
1434
2165
  },
1435
2166
  props: {
1436
2167
  isRoot: true,
@@ -1438,20 +2169,34 @@ export class Service extends DatabaseService<Model> {
1438
2169
  });
1439
2170
 
1440
2171
  monitorStatusId = monitor?.currentMonitorStatusId || null;
2172
+
2173
+ if (monitorStatusId) {
2174
+ nextReachable = monitor?.currentMonitorStatus?.isOfflineState !== true;
2175
+ }
1441
2176
  }
1442
2177
 
1443
2178
  const currentStampId: string | null =
1444
2179
  device.currentMonitorStatusId?.toString() || null;
1445
2180
  const nextStampId: string | null = monitorStatusId?.toString() || null;
1446
2181
 
1447
- if (currentStampId === nextStampId) {
2182
+ /*
2183
+ * A NULL column reads back as undefined on the model; both mean "no
2184
+ * verdict", and comparing them as one keeps a device that already
2185
+ * agrees from being rewritten on every save.
2186
+ */
2187
+ const currentReachable: boolean | null =
2188
+ typeof device.isReachable === "boolean" ? device.isReachable : null;
2189
+
2190
+ if (currentStampId === nextStampId && currentReachable === nextReachable) {
1448
2191
  return;
1449
2192
  }
1450
2193
 
2194
+ // One write, so the two columns can never be seen disagreeing.
1451
2195
  await this.updateColumnsByIdWithoutHooks({
1452
2196
  id: data.deviceId,
1453
2197
  data: {
1454
2198
  currentMonitorStatusId: monitorStatusId,
2199
+ isReachable: nextReachable,
1455
2200
  },
1456
2201
  });
1457
2202
 
@@ -1485,10 +2230,116 @@ export class Service extends DatabaseService<Model> {
1485
2230
  );
1486
2231
 
1487
2232
  if (isMethodWrite || isMonitorWrite) {
2233
+ // Same parse as onBeforeUpdate: only a plain string is a method.
2234
+ const writtenMethod: unknown = (
2235
+ onUpdate.updateBy.data as unknown as Record<string, unknown>
2236
+ )["monitoringMethod"];
2237
+ const becomesMonitorBacked: boolean =
2238
+ isMethodWrite &&
2239
+ typeof writtenMethod === "string" &&
2240
+ NetworkDeviceMonitoringMethodUtil.isMonitorBacked(writtenMethod);
2241
+
2242
+ /*
2243
+ * Recorded by onBeforeUpdate on every method write. Absent on a
2244
+ * binding-only write, where nothing can have transitioned.
2245
+ */
2246
+ const wasMonitorBackedByDeviceId: Record<string, boolean> =
2247
+ (onUpdate.carryForward as DeviceUpdateCarryForward | null)
2248
+ ?.wasMonitorBackedByDeviceId || {};
2249
+
1488
2250
  for (const deviceId of updatedItemIds) {
2251
+ const wasMonitorBacked: boolean | undefined =
2252
+ wasMonitorBackedByDeviceId[deviceId.toString()];
2253
+
2254
+ /*
2255
+ * Probe -> Monitor: the probe's last findings are now residue on a
2256
+ * device nothing polls, and they would keep feeding the legacy
2257
+ * staleness rule and the "degraded" query. Cleared as root here
2258
+ * rather than on the caller's payload (see onBeforeUpdate for the
2259
+ * permission reason), and BEFORE the re-stamp, so a device bound
2260
+ * in the same write ends up with its monitor's verdict rather
2261
+ * than the walk's. A device the snapshot did not record is
2262
+ * cleared too: the write is idempotent, and "unknown" must not
2263
+ * mean "keep the residue".
2264
+ */
2265
+ if (becomesMonitorBacked && wasMonitorBacked !== true) {
2266
+ try {
2267
+ await this.updateColumnsByIdWithoutHooks({
2268
+ id: deviceId,
2269
+ data: pollResidueReset(),
2270
+ });
2271
+ } catch (error) {
2272
+ /*
2273
+ * Bookkeeping, and separable from the re-stamp: the monitor's
2274
+ * verdict below still lands, and a set isReachable keeps the
2275
+ * legacy freshness branch out of play even with the dates
2276
+ * left behind.
2277
+ */
2278
+ logger.error(
2279
+ `Error in NetworkDeviceService.onUpdateSuccess poll residue reset for device ${deviceId.toString()}: ${error}`,
2280
+ );
2281
+ }
2282
+ }
2283
+
2284
+ /*
2285
+ * Monitor -> Probe: the mirror image. Arriving at monitor-backed
2286
+ * turned polling off (onBeforeUpdate), so leaving it turns polling
2287
+ * back on — otherwise the device would sit on "Pending" under a
2288
+ * method whose whole point is that the probe polls it. Decided
2289
+ * per device from the snapshot, never from the payload: one bulk
2290
+ * write of "Probe" also matches devices that already were Probe,
2291
+ * and one of those may have had polling turned off on purpose.
2292
+ * A root write, like the residue reset above, because the two
2293
+ * columns are updatable by fewer roles than the method is.
2294
+ * `nextPollAt = now` makes the device due at once rather than at
2295
+ * whatever moment its last claim — months ago, or never — left
2296
+ * behind. The caller's own word wins when it says the opposite:
2297
+ * a payload writing `isPollingEnabled: false` beside the method
2298
+ * wants a Probe device that is not polled yet. No probe is
2299
+ * required here — the forms require one, the API and Terraform
2300
+ * may assign it in a later write — and a Probe device without one
2301
+ * is simply not claimed until it has one.
2302
+ */
2303
+ const isMonitorToProbeTransition: boolean =
2304
+ wasMonitorBacked === true && !becomesMonitorBacked;
2305
+ const payloadTurnsPollingOff: boolean =
2306
+ dataKeys.includes("isPollingEnabled") &&
2307
+ (onUpdate.updateBy.data as unknown as Record<string, unknown>)[
2308
+ "isPollingEnabled"
2309
+ ] === false;
2310
+
2311
+ if (isMonitorToProbeTransition && !payloadTurnsPollingOff) {
2312
+ try {
2313
+ await this.updateColumnsByIdWithoutHooks({
2314
+ id: deviceId,
2315
+ data: {
2316
+ isPollingEnabled: true,
2317
+ nextPollAt: OneUptimeDate.getCurrentDate(),
2318
+ },
2319
+ });
2320
+ } catch (error) {
2321
+ /*
2322
+ * Bookkeeping, and separable from the re-stamp below: the
2323
+ * stale stamp still goes, and the operator can turn polling
2324
+ * on from Settings if this write was the one that failed.
2325
+ */
2326
+ logger.error(
2327
+ `Error in NetworkDeviceService.onUpdateSuccess polling restore for device ${deviceId.toString()}: ${error}`,
2328
+ );
2329
+ }
2330
+ }
2331
+
2332
+ /*
2333
+ * Only a device that WAS monitor-backed and now is not may have
2334
+ * its stamp cleared. The Settings form re-sends monitoringMethod
2335
+ * on every save, so "the payload says Probe" is not a transition —
2336
+ * treating it as one wiped the stamp a Network Device monitor had
2337
+ * put on every Probe device that was ever saved.
2338
+ */
1489
2339
  await this.refreshStampedMonitorStatus({
1490
2340
  deviceId: deviceId,
1491
- clearWhenNotMonitorBacked: isMethodWrite,
2341
+ clearWhenNotMonitorBacked:
2342
+ wasMonitorBacked === true && !becomesMonitorBacked,
1492
2343
  });
1493
2344
  }
1494
2345
  }
@@ -1613,9 +2464,103 @@ export class Service extends DatabaseService<Model> {
1613
2464
  );
1614
2465
  }
1615
2466
 
2467
+ try {
2468
+ await this.reconcileAlertPoliciesAfterUpdate(onUpdate, updatedItemIds);
2469
+ } catch (error) {
2470
+ /*
2471
+ * Isolated from the site maintenance above for the same reason that is
2472
+ * isolated from the status re-stamp: a policy that cannot provision
2473
+ * must not cost the device its site rollup, and the five-minute sweep
2474
+ * recomputes the same difference either way.
2475
+ */
2476
+ logger.error(
2477
+ `Error in NetworkDeviceService.onUpdateSuccess alert policy reconciliation: ${error}`,
2478
+ );
2479
+ }
2480
+
1616
2481
  return onUpdate;
1617
2482
  }
1618
2483
 
2484
+ /*
2485
+ * Keep the device's policy-provisioned monitors in step with what the
2486
+ * update just changed about it.
2487
+ *
2488
+ * INLINE ONLY FOR A HANDFUL OF DEVICES. Reconciling one device is a few
2489
+ * queries and, at most, one monitor create — worth doing inside the write
2490
+ * so the monitor is there by the operator's next page load. A BULK write is
2491
+ * a different animal: "move 1,200 devices into this site" or "archive the
2492
+ * warehouse" matches thousands of rows, and reconciling thousands of
2493
+ * devices inside the request would turn one statement into an hour of
2494
+ * monitor provisioning with the caller still waiting on it. Past
2495
+ * MAX_INLINE_RECONCILE_DEVICES the write returns and the five-minute sweep
2496
+ * converges the fleet — it computes the same difference from the same
2497
+ * columns, so nothing is lost but latency.
2498
+ *
2499
+ * The project comes from the pre-write snapshot rather than from
2500
+ * props.tenantId, because a root caller (a worker, a data migration) has no
2501
+ * tenant and its update can legitimately span projects.
2502
+ */
2503
+ private async reconcileAlertPoliciesAfterUpdate(
2504
+ onUpdate: OnUpdate<Model>,
2505
+ updatedItemIds: Array<ObjectID>,
2506
+ ): Promise<void> {
2507
+ const dataKeys: Array<string> = Object.keys(onUpdate.updateBy.data || {});
2508
+
2509
+ if (!isAlertPolicyRelevantWrite(dataKeys) || updatedItemIds.length === 0) {
2510
+ return;
2511
+ }
2512
+
2513
+ if (updatedItemIds.length > MAX_INLINE_RECONCILE_DEVICES) {
2514
+ logger.debug(
2515
+ `NetworkDeviceService.onUpdateSuccess: ${updatedItemIds.length} devices changed an alert-policy scope column; leaving reconciliation to the NetworkAlertPolicy sweep.`,
2516
+ );
2517
+
2518
+ return;
2519
+ }
2520
+
2521
+ const previousDevices: Array<Model> =
2522
+ (onUpdate.carryForward?.previousDevices as Array<Model>) || [];
2523
+
2524
+ const projectIdByDeviceId: Map<string, ObjectID> = new Map<
2525
+ string,
2526
+ ObjectID
2527
+ >();
2528
+
2529
+ for (const previousDevice of previousDevices) {
2530
+ if (previousDevice.id && previousDevice.projectId) {
2531
+ projectIdByDeviceId.set(
2532
+ previousDevice.id.toString(),
2533
+ previousDevice.projectId,
2534
+ );
2535
+ }
2536
+ }
2537
+
2538
+ for (const deviceId of updatedItemIds) {
2539
+ const projectId: ObjectID | undefined =
2540
+ projectIdByDeviceId.get(deviceId.toString()) ||
2541
+ onUpdate.updateBy.props.tenantId ||
2542
+ undefined;
2543
+
2544
+ if (!projectId) {
2545
+ /*
2546
+ * No snapshot row and no tenant: the update matched a device this
2547
+ * hook cannot attribute to a project, so it cannot be reconciled
2548
+ * safely. The sweep, which starts from the policies, will reach it.
2549
+ */
2550
+ logger.debug(
2551
+ `NetworkDeviceService.onUpdateSuccess: no project known for device ${deviceId.toString()}; leaving its alert-policy monitors to the sweep.`,
2552
+ );
2553
+
2554
+ continue;
2555
+ }
2556
+
2557
+ await NetworkAlertPolicyEngineService.reconcileDevice({
2558
+ projectId: projectId,
2559
+ deviceId: deviceId,
2560
+ });
2561
+ }
2562
+ }
2563
+
1619
2564
  /*
1620
2565
  * True when an update that touched an identity column is worth re-running
1621
2566
  * the assignment rules for.
@@ -2014,6 +2959,10 @@ export class Service extends DatabaseService<Model> {
2014
2959
  * Suspended projects are skipped for the same reason monitor claiming
2015
2960
  * skips them; archived devices keep polling on purpose ("archived devices
2016
2961
  * keep collecting telemetry").
2962
+ *
2963
+ * The Probe join is a TENANCY backstop rather than a lookup — nothing from
2964
+ * the probe row is selected. See the predicate for why the write-time
2965
+ * guard is not enough on its own.
2017
2966
  */
2018
2967
  @CaptureSpan()
2019
2968
  public async claimDevicesForPolling(data: {
@@ -2028,12 +2977,22 @@ export class Service extends DatabaseService<Model> {
2028
2977
  SELECT nd."_id", nd."pollingIntervalInMinutes"
2029
2978
  FROM "NetworkDevice" nd
2030
2979
  INNER JOIN "Project" p ON nd."projectId" = p."_id"
2980
+ INNER JOIN "Probe" pr ON nd."probeId" = pr."_id"
2031
2981
  WHERE nd."probeId" = $1
2032
2982
  AND nd."isPollingEnabled" = true
2033
2983
  AND nd."deletedAt" IS NULL
2034
2984
  AND nd."hostname" IS NOT NULL
2035
- -- A monitor-backed device has no credentials to walk with. NULL is
2036
- -- every device created before the column existed: those are SNMP.
2985
+ -- The tenancy backstop. onBeforeCreate/onBeforeUpdate refuse a
2986
+ -- probe that is not attachable to the device's project, but rows
2987
+ -- written before those guards existed are still on disk, and a
2988
+ -- probe that can CLAIM a device reads its hostname and its SNMP
2989
+ -- credentials. A global probe has no project and may poll anyone;
2990
+ -- anything else must match the device's own project or the row is
2991
+ -- simply never handed out. isGlobalProbe is NOT NULL DEFAULT false,
2992
+ -- so there is no third state here to reason about.
2993
+ AND (pr."isGlobalProbe" = true OR pr."projectId" = nd."projectId")
2994
+ -- Nothing polls a monitor-backed device. NULL is every device
2995
+ -- created before the column existed: those are probe-polled.
2037
2996
  AND (nd."monitoringMethod" IS NULL OR nd."monitoringMethod" <> 'Monitor')
2038
2997
  AND nd."nextPollAt" <= $2
2039
2998
  AND p."deletedAt" IS NULL