@oneuptime/common 12.0.32 → 12.0.33

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 (597) hide show
  1. package/Models/AnalyticsModels/Span.ts +14 -0
  2. package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
  3. package/Models/DatabaseModels/Index.ts +10 -0
  4. package/Models/DatabaseModels/Monitor.ts +76 -0
  5. package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +176 -1
  7. package/Models/DatabaseModels/NetworkSite.ts +201 -2
  8. package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
  9. package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
  10. package/Models/DatabaseModels/TelemetryException.ts +119 -0
  11. package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
  12. package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
  13. package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
  14. package/Server/API/EnterpriseLicenseAPI.ts +391 -64
  15. package/Server/API/LlmProviderAPI.ts +137 -22
  16. package/Server/EnvironmentConfig.ts +14 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  24. package/Server/Infrastructure/QueueWorker.ts +38 -8
  25. package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
  26. package/Server/Middleware/ProjectAuthorization.ts +11 -0
  27. package/Server/Middleware/SCIMAuthorization.ts +12 -0
  28. package/Server/Middleware/TelemetryIngest.ts +11 -0
  29. package/Server/Services/AIBillingService.ts +101 -27
  30. package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
  31. package/Server/Services/EnterpriseLicenseService.ts +55 -0
  32. package/Server/Services/Index.ts +10 -0
  33. package/Server/Services/MonitorService.ts +143 -21
  34. package/Server/Services/MonitorStatusTimelineService.ts +150 -8
  35. package/Server/Services/MonitorTemplateService.ts +217 -1
  36. package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
  37. package/Server/Services/NetworkAlertPolicyService.ts +944 -0
  38. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +9 -10
  39. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
  40. package/Server/Services/NetworkDeviceService.ts +1032 -73
  41. package/Server/Services/NetworkSiteService.ts +1502 -129
  42. package/Server/Services/NetworkSiteTypeService.ts +1216 -0
  43. package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
  44. package/Server/Services/NotificationService.ts +118 -28
  45. package/Server/Services/ProjectService.ts +105 -48
  46. package/Server/Services/StatusPagePrivateUserService.ts +103 -3
  47. package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
  48. package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
  49. package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
  50. package/Server/Services/UserNotificationSettingService.ts +62 -25
  51. package/Server/Services/UserService.ts +95 -0
  52. package/Server/Types/Database/QueryHelper.ts +2 -2
  53. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
  54. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
  55. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
  56. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
  57. package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
  58. package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
  59. package/Server/Utils/DataSource/HttpFetch.ts +9 -2
  60. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
  61. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
  62. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
  63. package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
  64. package/Server/Utils/LLM/LLMService.ts +78 -0
  65. package/Server/Utils/LogRedaction.ts +8 -0
  66. package/Server/Utils/Logger.ts +79 -1
  67. package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
  68. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
  69. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
  70. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  71. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
  72. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
  73. package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
  74. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -0
  75. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
  76. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
  77. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
  78. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
  79. package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
  80. package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
  81. package/Server/Utils/OutboundUserAgent.ts +152 -0
  82. package/Server/Utils/StartServer.ts +51 -19
  83. package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
  84. package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
  85. package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
  86. package/Server/Utils/Telemetry.ts +198 -51
  87. package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
  88. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
  89. package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
  90. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
  91. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
  92. package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
  93. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -9
  94. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
  95. package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
  96. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
  97. package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
  98. package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
  99. package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
  100. package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
  101. package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
  102. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
  103. package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
  104. package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
  105. package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
  106. package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
  107. package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
  108. package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
  109. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
  110. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
  111. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
  112. package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
  113. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
  114. package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
  115. package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
  116. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
  117. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
  118. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
  119. package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
  120. package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
  121. package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
  122. package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
  123. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
  124. package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
  125. package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
  126. package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
  127. package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
  128. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +47 -4
  129. package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
  130. package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
  131. package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
  132. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
  133. package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
  134. package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
  135. package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
  136. package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
  137. package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
  138. package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
  139. package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
  140. package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
  141. package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
  142. package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
  143. package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
  144. package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
  145. package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
  146. package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
  147. package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
  148. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +856 -0
  149. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +102 -1
  150. package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
  151. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
  152. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
  153. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
  154. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
  155. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
  156. package/Tests/Server/Utils/Captcha.test.ts +422 -0
  157. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
  158. package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
  159. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
  160. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
  161. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
  162. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
  163. package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
  164. package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
  165. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
  166. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
  167. package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
  168. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
  169. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
  170. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
  171. package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
  172. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
  173. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
  174. package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
  175. package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
  176. package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
  177. package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
  178. package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
  179. package/Tests/Server/Utils/Telemetry.test.ts +456 -66
  180. package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
  181. package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
  182. package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
  183. package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
  184. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
  185. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
  186. package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
  187. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
  188. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
  189. package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
  190. package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
  191. package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
  192. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
  193. package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
  194. package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
  195. package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
  196. package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
  197. package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
  198. package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
  199. package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
  200. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
  201. package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
  202. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
  203. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
  204. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  205. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
  206. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
  207. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
  208. package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
  209. package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
  210. package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
  211. package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
  212. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
  213. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
  214. package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
  215. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
  216. package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
  217. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
  218. package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
  219. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
  220. package/Types/AI/ExceptionAIClassification.ts +10 -24
  221. package/Types/Email/EmailTemplateType.ts +2 -0
  222. package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
  223. package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
  224. package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
  225. package/Types/Exception/ApiException.ts +10 -0
  226. package/Types/Exception/BadDataException.ts +11 -0
  227. package/Types/Exception/BadRequestException.ts +11 -0
  228. package/Types/Exception/Exception.ts +65 -0
  229. package/Types/Exception/ForbiddenException.ts +10 -0
  230. package/Types/Exception/NotAuthenticatedException.ts +10 -0
  231. package/Types/Exception/NotAuthorizedException.ts +10 -0
  232. package/Types/Exception/NotFoundException.ts +11 -0
  233. package/Types/Exception/PayloadTooLargeException.ts +11 -0
  234. package/Types/Exception/PaymentRequiredException.ts +10 -0
  235. package/Types/Exception/ServiceUnavailableException.ts +10 -0
  236. package/Types/Exception/SsoAuthorizationException.ts +10 -0
  237. package/Types/Exception/TenantNotFoundException.ts +11 -0
  238. package/Types/Exception/TimeoutException.ts +10 -0
  239. package/Types/Exception/TooManyRequestsException.ts +10 -0
  240. package/Types/Exception/UnableToReachServer.ts +10 -0
  241. package/Types/Exception/WebsiteRequestException.ts +10 -0
  242. package/Types/Monitor/CriteriaFilter.ts +60 -2
  243. package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
  244. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
  245. package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
  246. package/Types/Monitor/MonitorMetricType.ts +71 -0
  247. package/Types/Monitor/MonitorStep.ts +76 -0
  248. package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
  249. package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
  250. package/Types/Monitor/MonitorType.ts +47 -1
  251. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
  252. package/Types/Monitor/SqlConnectionConfig.ts +31 -0
  253. package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
  254. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
  255. package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
  256. package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
  257. package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
  258. package/Types/Permission.ts +90 -0
  259. package/Types/Probe/ProbeMonitorResponse.ts +16 -0
  260. package/Types/Telemetry/ErrorClass.ts +274 -0
  261. package/Types/Telemetry/UnitOfWork.ts +59 -0
  262. package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
  263. package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
  264. package/UI/Components/Modal/Modal.tsx +2 -8
  265. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  266. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
  267. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
  268. package/UI/Components/SideMenu/SideMenu.tsx +123 -5
  269. package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
  270. package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
  271. package/UI/Components/SideOver/SideOver.tsx +21 -20
  272. package/UI/Utils/PageScrollLock.ts +79 -3
  273. package/UI/Utils/PermissionGate.ts +61 -0
  274. package/UI/Utils/SensitiveUrlToken.ts +112 -0
  275. package/UI/Utils/TestLLMProvider.ts +11 -0
  276. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
  277. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
  278. package/Utils/Monitor/MonitorMetricType.ts +153 -1
  279. package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
  280. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
  281. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
  282. package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
  283. package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
  284. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
  285. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
  286. package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
  287. package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
  288. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
  289. package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
  290. package/build/dist/Models/AnalyticsModels/Span.js +14 -0
  291. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  292. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
  293. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  294. package/build/dist/Models/DatabaseModels/Index.js +10 -0
  295. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  296. package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
  297. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  298. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
  299. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
  300. package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
  301. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  302. package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
  303. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  304. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
  305. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
  306. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
  307. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
  308. package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
  309. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
  311. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
  312. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
  313. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
  314. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
  315. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
  316. package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
  317. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  318. package/build/dist/Server/API/LlmProviderAPI.js +108 -13
  319. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  320. package/build/dist/Server/EnvironmentConfig.js +12 -0
  321. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  322. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
  323. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
  324. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
  325. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
  326. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
  327. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
  328. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
  329. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
  330. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
  331. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
  332. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
  333. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
  334. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  335. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  336. package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
  337. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  338. package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
  339. package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
  340. package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
  341. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  342. package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
  343. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
  344. package/build/dist/Server/Middleware/TelemetryIngest.js +11 -0
  345. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  346. package/build/dist/Server/Services/AIBillingService.js +70 -16
  347. package/build/dist/Server/Services/AIBillingService.js.map +1 -1
  348. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
  349. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
  350. package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
  351. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  352. package/build/dist/Server/Services/Index.js +10 -0
  353. package/build/dist/Server/Services/Index.js.map +1 -1
  354. package/build/dist/Server/Services/MonitorService.js +119 -21
  355. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  356. package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
  357. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  358. package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
  359. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  360. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
  361. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
  362. package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
  363. package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
  364. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +10 -9
  365. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  366. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
  367. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  368. package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
  369. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  370. package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
  371. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  372. package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
  373. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
  374. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
  375. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
  376. package/build/dist/Server/Services/NotificationService.js +80 -17
  377. package/build/dist/Server/Services/NotificationService.js.map +1 -1
  378. package/build/dist/Server/Services/ProjectService.js +66 -30
  379. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  380. package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
  381. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  382. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
  383. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
  384. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
  385. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
  386. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
  387. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
  388. package/build/dist/Server/Services/UserNotificationSettingService.js +46 -20
  389. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  390. package/build/dist/Server/Services/UserService.js +90 -0
  391. package/build/dist/Server/Services/UserService.js.map +1 -1
  392. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  393. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  394. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
  395. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  396. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
  397. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  398. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
  399. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  400. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
  401. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
  402. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
  403. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  404. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
  405. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
  407. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  408. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +91 -0
  409. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
  410. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -0
  411. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
  412. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
  413. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
  414. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
  415. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
  416. package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
  417. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  418. package/build/dist/Server/Utils/LogRedaction.js +8 -0
  419. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  420. package/build/dist/Server/Utils/Logger.js +63 -1
  421. package/build/dist/Server/Utils/Logger.js.map +1 -1
  422. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
  423. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
  424. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  425. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  426. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
  427. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  429. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  430. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +37 -0
  431. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
  433. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  435. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -0
  437. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
  439. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  440. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
  441. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  442. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
  443. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  444. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
  445. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  446. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
  447. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
  448. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
  449. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
  450. package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
  451. package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
  452. package/build/dist/Server/Utils/StartServer.js +38 -14
  453. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  454. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
  455. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  456. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
  457. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
  458. package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
  459. package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
  460. package/build/dist/Server/Utils/Telemetry.js +162 -46
  461. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  462. package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
  463. package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
  464. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  465. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  466. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
  467. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
  468. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
  469. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
  470. package/build/dist/Types/Exception/ApiException.js +9 -0
  471. package/build/dist/Types/Exception/ApiException.js.map +1 -1
  472. package/build/dist/Types/Exception/BadDataException.js +10 -0
  473. package/build/dist/Types/Exception/BadDataException.js.map +1 -1
  474. package/build/dist/Types/Exception/BadRequestException.js +10 -0
  475. package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
  476. package/build/dist/Types/Exception/Exception.js +56 -0
  477. package/build/dist/Types/Exception/Exception.js.map +1 -1
  478. package/build/dist/Types/Exception/ForbiddenException.js +9 -0
  479. package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
  480. package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
  481. package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
  482. package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
  483. package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
  484. package/build/dist/Types/Exception/NotFoundException.js +10 -0
  485. package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
  486. package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
  487. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
  488. package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
  489. package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
  490. package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
  491. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
  492. package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
  493. package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
  494. package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
  495. package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
  496. package/build/dist/Types/Exception/TimeoutException.js +9 -0
  497. package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
  498. package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
  499. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
  500. package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
  501. package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
  502. package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
  503. package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
  504. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
  505. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  506. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
  507. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
  508. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
  509. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
  510. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
  511. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  512. package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
  513. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  514. package/build/dist/Types/Monitor/MonitorStep.js +54 -0
  515. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  516. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
  517. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
  518. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  519. package/build/dist/Types/Monitor/MonitorType.js +45 -1
  520. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  521. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
  522. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  523. package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
  524. package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
  525. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
  526. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
  527. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
  528. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
  529. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
  530. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
  531. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
  532. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
  533. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
  534. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
  535. package/build/dist/Types/Permission.js +80 -0
  536. package/build/dist/Types/Permission.js.map +1 -1
  537. package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
  538. package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
  539. package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
  540. package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
  541. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
  542. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  543. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
  544. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  545. package/build/dist/UI/Components/Modal/Modal.js +2 -7
  546. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  547. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
  548. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  549. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
  550. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  551. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
  552. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  553. package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
  554. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  555. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
  556. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  557. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
  558. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  559. package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
  560. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  561. package/build/dist/UI/Utils/PageScrollLock.js +31 -3
  562. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
  563. package/build/dist/UI/Utils/PermissionGate.js +42 -1
  564. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  565. package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
  566. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
  567. package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
  568. package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
  569. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
  570. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
  571. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
  572. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  573. package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
  574. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  575. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
  576. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  577. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
  578. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
  579. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
  580. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  581. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
  582. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
  583. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
  584. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
  585. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
  586. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  587. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
  588. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  589. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
  590. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
  591. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
  592. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
  593. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
  594. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  595. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
  596. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
  597. package/package.json +2 -2
@@ -17,6 +17,9 @@ import SnmpOid from "../../../../Types/Monitor/SnmpMonitor/SnmpOid";
17
17
  import SnmpVendorTemplateUtil, {
18
18
  SnmpVendorTemplate,
19
19
  } from "../../../../Types/Monitor/SnmpMonitor/SnmpVendorTemplate";
20
+ import NetworkDeviceMonitoringMethod from "../../../../Types/NetworkDevice/NetworkDeviceMonitoringMethod";
21
+ import { NetworkDevicePollMode } from "../../../../Server/Utils/Monitor/NetworkDeviceHydrationUtil";
22
+ import logger from "../../../../Server/Utils/Logger";
20
23
 
21
24
  /*
22
25
  * NetworkInventoryUtil.updateFromWalk is the single writer that keeps the
@@ -153,9 +156,17 @@ function existingInterface(interfaceIndex: number): NetworkInterface {
153
156
  return row;
154
157
  }
155
158
 
159
+ /*
160
+ * A poll that ran a walk. With no pollMode this is what an old probe's walk
161
+ * looks like to the util (the processor stamps "snmp" for it); pass
162
+ * pollMode "snmp" for a ping-first probe's walk.
163
+ */
156
164
  async function runWalk(
157
165
  snmpFields?: Partial<SnmpMonitorResponse>,
158
- options?: { isOnline?: boolean | undefined },
166
+ options?: {
167
+ isOnline?: boolean | undefined;
168
+ pollMode?: NetworkDevicePollMode | undefined;
169
+ },
159
170
  ): Promise<SnmpMonitorResponse> {
160
171
  const snmpResponse: SnmpMonitorResponse = buildSnmpResponse(snmpFields);
161
172
 
@@ -164,11 +175,23 @@ async function runWalk(
164
175
  deviceId: new ObjectID(DEVICE_ID),
165
176
  snmpResponse: snmpResponse,
166
177
  isOnline: options && "isOnline" in options ? options.isOnline : true,
178
+ pollMode: options?.pollMode,
167
179
  });
168
180
 
169
181
  return snmpResponse;
170
182
  }
171
183
 
184
+ // A ping-only poll: the device has no usable credentials, so no walk ran.
185
+ async function runPingOnlyPoll(options: { isOnline: boolean }): Promise<void> {
186
+ await NetworkInventoryUtil.updateFromWalk({
187
+ projectId: new ObjectID(PROJECT_ID),
188
+ deviceId: new ObjectID(DEVICE_ID),
189
+ snmpResponse: undefined,
190
+ isOnline: options.isOnline,
191
+ pollMode: "ping",
192
+ });
193
+ }
194
+
172
195
  beforeEach(() => {
173
196
  jest.spyOn(OneUptimeDate, "getCurrentDate").mockReturnValue(NOW);
174
197
  });
@@ -299,7 +322,7 @@ describe("NetworkInventoryUtil.updateFromWalk — project-membership guard", ()
299
322
  * called both of them Down.
300
323
  */
301
324
  describe("NetworkInventoryUtil.updateFromWalk — reachability recording", () => {
302
- test("a reachable poll stamps all three columns", async () => {
325
+ test("a reachable poll stamps all three columns - and, for a walk, the SNMP pair", async () => {
303
326
  mockServices();
304
327
 
305
328
  await runWalk();
@@ -309,6 +332,8 @@ describe("NetworkInventoryUtil.updateFromWalk — reachability recording", () =>
309
332
  expect(update["lastPolledAt"]).toEqual(NOW);
310
333
  expect(update["isReachable"]).toBe(true);
311
334
  expect(update["lastSeenAt"]).toEqual(NOW);
335
+ expect(update["isSnmpReachable"]).toBe(true);
336
+ expect(update["lastSnmpSeenAt"]).toEqual(NOW);
312
337
  });
313
338
 
314
339
  test("an unreachable poll with no walk data still records the attempt", async () => {
@@ -334,23 +359,35 @@ describe("NetworkInventoryUtil.updateFromWalk — reachability recording", () =>
334
359
  expect(update["isReachable"]).toBe(false);
335
360
  // The device did not answer, so its last contact must not move.
336
361
  expect(update).not.toHaveProperty("lastSeenAt");
362
+ // The walk was attempted and failed: false, not NULL.
363
+ expect(update["isSnmpReachable"]).toBe(false);
364
+ expect(update).not.toHaveProperty("lastSnmpSeenAt");
337
365
  });
338
366
 
339
- test("an unreachable poll with walk data still enriches but never stamps lastSeenAt", async () => {
367
+ /*
368
+ * Inventory comes only from a successful walk. A failed walk carries no
369
+ * system group in practice, and reading whatever a malformed failure did
370
+ * carry would let a session that never opened rewrite sysName (and so
371
+ * re-run site-assignment rules) or clear the LLDP snapshot.
372
+ */
373
+ test("a failed walk records the attempt but never enriches inventory", async () => {
340
374
  mockServices();
341
375
 
342
376
  await runWalk(
343
377
  {
344
378
  isOnline: false,
345
379
  systemInfo: { sysName: "core-sw-01" },
380
+ lldpNeighbors: [],
346
381
  },
347
382
  { isOnline: false },
348
383
  );
349
384
 
350
385
  const update: DeviceUpdatePayload = deviceUpdatePayload();
351
386
 
352
- expect(update["sysName"]).toBe("core-sw-01");
387
+ expect(update).not.toHaveProperty("sysName");
388
+ expect(update).not.toHaveProperty("lldpNeighbors");
353
389
  expect(update["isReachable"]).toBe(false);
390
+ expect(update["isSnmpReachable"]).toBe(false);
354
391
  expect(update["lastPolledAt"]).toEqual(NOW);
355
392
  expect(update).not.toHaveProperty("lastSeenAt");
356
393
  });
@@ -810,17 +847,175 @@ describe("NetworkInventoryUtil.updateFromWalk — walks without interfaces", ()
810
847
  isOnline: true,
811
848
  });
812
849
 
813
- // Exactly the reachability columns and nothing else — no walk, no data.
850
+ /*
851
+ * Exactly the reachability columns and nothing else — no walk, no
852
+ * data. isSnmpReachable is NULL, not false: nothing was walked. (No
853
+ * pollMode reads as "snmp", so the interface counts are left alone as
854
+ * they are across any failed walk.)
855
+ */
814
856
  expect(deviceUpdatePayload()).toEqual({
815
857
  lastPolledAt: NOW,
816
858
  isReachable: true,
817
859
  lastSeenAt: NOW,
860
+ isSnmpReachable: null,
818
861
  });
819
862
  expect(interfaceFindSpy).not.toHaveBeenCalled();
820
863
  expect(interfaceUpsertSpy).not.toHaveBeenCalled();
821
864
  });
822
865
  });
823
866
 
867
+ /*
868
+ * Ping-first polling. The three device columns answer "did the device
869
+ * answer ping or SNMP"; the SNMP pair answers "did the WALK", and NULL there
870
+ * means "no walk ran" - which is what a credential-less device looks like
871
+ * on every poll and must never read as "SNMP down".
872
+ */
873
+ describe("NetworkInventoryUtil.updateFromWalk — ping-first column matrix", () => {
874
+ test("a reachable ping-only poll: device columns stamped, walk columns NULL, interface counts NULL, no inventory", async () => {
875
+ mockServices();
876
+
877
+ await runPingOnlyPoll({ isOnline: true });
878
+
879
+ expect(deviceUpdatePayload()).toEqual({
880
+ lastPolledAt: NOW,
881
+ isReachable: true,
882
+ lastSeenAt: NOW,
883
+ isSnmpReachable: null,
884
+ interfacesTotal: null,
885
+ interfacesUp: null,
886
+ interfacesDown: null,
887
+ });
888
+ expect(interfaceUpsertSpy).not.toHaveBeenCalled();
889
+ expect(endpointUpsertSpy).not.toHaveBeenCalled();
890
+ });
891
+
892
+ test("an unreachable ping-only poll: the attempt is recorded, nothing was seen, walk columns NULL", async () => {
893
+ mockServices();
894
+
895
+ await runPingOnlyPoll({ isOnline: false });
896
+
897
+ expect(deviceUpdatePayload()).toEqual({
898
+ lastPolledAt: NOW,
899
+ isReachable: false,
900
+ isSnmpReachable: null,
901
+ interfacesTotal: null,
902
+ interfacesUp: null,
903
+ interfacesDown: null,
904
+ });
905
+ });
906
+
907
+ test("an snmp-mode poll whose walk succeeded stamps the SNMP pair and the counts beside the device columns", async () => {
908
+ mockServices();
909
+
910
+ await runWalk(
911
+ {
912
+ interfaces: [
913
+ walkedInterface({ interfaceIndex: 1, isOperationallyUp: true }),
914
+ walkedInterface({ interfaceIndex: 2, isOperationallyUp: false }),
915
+ ],
916
+ },
917
+ { isOnline: true, pollMode: "snmp" },
918
+ );
919
+
920
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
921
+
922
+ expect(update["isReachable"]).toBe(true);
923
+ expect(update["lastSeenAt"]).toEqual(NOW);
924
+ expect(update["isSnmpReachable"]).toBe(true);
925
+ expect(update["lastSnmpSeenAt"]).toEqual(NOW);
926
+ expect(update["interfacesTotal"]).toBe(2);
927
+ expect(update["interfacesUp"]).toBe(1);
928
+ expect(update["interfacesDown"]).toBe(1);
929
+ });
930
+
931
+ /*
932
+ * The credentials are wrong, the agent is off, or an ACL blocks 161 - but
933
+ * the device answers ping. It is Up; its walk is down; the last good
934
+ * interface counts stay (the best estimate until the next good walk);
935
+ * and nothing the failed session "found" is written as inventory.
936
+ */
937
+ test("an snmp-mode poll where ping answered but the walk failed: device up, walk down, counts and inventory untouched", async () => {
938
+ mockServices();
939
+
940
+ await runWalk(
941
+ {
942
+ isOnline: false,
943
+ responseTimeInMs: 0,
944
+ failureCause: "SNMP timed out after 3 attempts",
945
+ systemInfo: { sysName: "should-not-land" },
946
+ },
947
+ { isOnline: true, pollMode: "snmp" },
948
+ );
949
+
950
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
951
+
952
+ expect(update["lastPolledAt"]).toEqual(NOW);
953
+ expect(update["isReachable"]).toBe(true);
954
+ expect(update["lastSeenAt"]).toEqual(NOW);
955
+ expect(update["isSnmpReachable"]).toBe(false);
956
+ expect(update).not.toHaveProperty("lastSnmpSeenAt");
957
+ expect(update).not.toHaveProperty("interfacesTotal");
958
+ expect(update).not.toHaveProperty("interfacesUp");
959
+ expect(update).not.toHaveProperty("interfacesDown");
960
+ expect(update).not.toHaveProperty("sysName");
961
+ });
962
+
963
+ test("an snmp-mode poll that failed both ways: device down, walk down, nothing seen", async () => {
964
+ mockServices();
965
+
966
+ await runWalk(
967
+ {
968
+ isOnline: false,
969
+ responseTimeInMs: 0,
970
+ failureCause: "SNMP timed out after 3 attempts",
971
+ },
972
+ { isOnline: false, pollMode: "snmp" },
973
+ );
974
+
975
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
976
+
977
+ expect(update["isReachable"]).toBe(false);
978
+ expect(update).not.toHaveProperty("lastSeenAt");
979
+ expect(update["isSnmpReachable"]).toBe(false);
980
+ expect(update).not.toHaveProperty("lastSnmpSeenAt");
981
+ });
982
+
983
+ /*
984
+ * A probe that predates ping-first polling only ever walked, so its walk
985
+ * verdict is the device verdict and both columns carry it - a credentialed
986
+ * device is never left with a NULL walk column by an old probe.
987
+ */
988
+ test("an old probe's walk (no pollMode) keeps the walk verdict for BOTH the device and the SNMP columns", async () => {
989
+ mockServices();
990
+
991
+ await runWalk({ isOnline: false }, { isOnline: false });
992
+ const failed: DeviceUpdatePayload = deviceUpdatePayload();
993
+
994
+ expect(failed["isReachable"]).toBe(false);
995
+ expect(failed["isSnmpReachable"]).toBe(false);
996
+
997
+ deviceUpdateSpy.mockClear();
998
+ await runWalk();
999
+ const good: DeviceUpdatePayload = deviceUpdatePayload();
1000
+
1001
+ expect(good["isReachable"]).toBe(true);
1002
+ expect(good["isSnmpReachable"]).toBe(true);
1003
+ expect(good["lastSeenAt"]).toEqual(NOW);
1004
+ expect(good["lastSnmpSeenAt"]).toEqual(NOW);
1005
+ });
1006
+
1007
+ test("a walk with no verdict at all counts as succeeded, matching the device convention", async () => {
1008
+ mockServices();
1009
+
1010
+ await runWalk({ isOnline: undefined as unknown as boolean });
1011
+
1012
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
1013
+
1014
+ expect(update["isSnmpReachable"]).toBe(true);
1015
+ expect(update["lastSnmpSeenAt"]).toEqual(NOW);
1016
+ });
1017
+ });
1018
+
824
1019
  describe("NetworkInventoryUtil.updateFromWalk — endpoint discovery", () => {
825
1020
  test("a walk without ARP/FDB arrays (collection off) never touches endpoints", async () => {
826
1021
  mockServices();
@@ -1034,3 +1229,154 @@ describe("NetworkInventoryUtil.updateFromWalk — vendor health template auto-ap
1034
1229
  expect(findArgs.select?.["oidTemplateId"]).toBe(true);
1035
1230
  });
1036
1231
  });
1232
+
1233
+ /*
1234
+ * A monitor-backed device (monitoringMethod "Monitor") is never meant to be
1235
+ * walked - its bound Monitor owns reachability. But claimDevicesForPolling
1236
+ * only excludes such rows at CLAIM time, so a device claimed as SNMP and
1237
+ * switched to Monitor before its walk result arrived still reaches this
1238
+ * writer. The poll verdict must not overwrite the monitor's: these cases
1239
+ * pin that the health columns (lastPolledAt / isReachable / lastSeenAt and
1240
+ * the cached interface counts) are withheld for such a row, that the rest
1241
+ * of the walk's inventory still lands, and that an SNMP walk is untouched.
1242
+ */
1243
+ describe("NetworkInventoryUtil.updateFromWalk — monitor-backed device guard", () => {
1244
+ const POLL_AND_INTERFACE_COLUMNS: Array<string> = [
1245
+ "lastPolledAt",
1246
+ "isReachable",
1247
+ "lastSeenAt",
1248
+ "isSnmpReachable",
1249
+ "lastSnmpSeenAt",
1250
+ "interfacesTotal",
1251
+ "interfacesUp",
1252
+ "interfacesDown",
1253
+ ];
1254
+
1255
+ function spyWarn(): jest.SpyInstance {
1256
+ return jest.spyOn(logger, "warn").mockImplementation(() => {
1257
+ return undefined;
1258
+ });
1259
+ }
1260
+
1261
+ test("a walk for a monitor-backed device leaves the poll and interface-count columns out and warns once", async () => {
1262
+ mockServices([], {
1263
+ monitoringMethod: NetworkDeviceMonitoringMethod.Monitor,
1264
+ });
1265
+ const warn: jest.SpyInstance = spyWarn();
1266
+
1267
+ await runWalk({
1268
+ systemInfo: { sysName: "ap-01" },
1269
+ interfaces: [
1270
+ walkedInterface({ interfaceIndex: 1, isOperationallyUp: true }),
1271
+ walkedInterface({ interfaceIndex: 2, isOperationallyUp: false }),
1272
+ ],
1273
+ });
1274
+
1275
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
1276
+
1277
+ // Inventory still lands...
1278
+ expect(update["sysName"]).toBe("ap-01");
1279
+ // ...but nothing that decides the device's health does.
1280
+ for (const column of POLL_AND_INTERFACE_COLUMNS) {
1281
+ expect(update).not.toHaveProperty(column);
1282
+ }
1283
+
1284
+ // The interface inventory itself is still recorded - it is not health.
1285
+ expect(interfaceUpsertSpy).toHaveBeenCalledTimes(1);
1286
+
1287
+ expect(warn).toHaveBeenCalledTimes(1);
1288
+ expect(String(warn.mock.calls[0]![0])).toContain(DEVICE_ID);
1289
+ });
1290
+
1291
+ test("an unreachable walk of a monitor-backed device with nothing else to record writes nothing", async () => {
1292
+ mockServices([], {
1293
+ monitoringMethod: NetworkDeviceMonitoringMethod.Monitor,
1294
+ });
1295
+ const warn: jest.SpyInstance = spyWarn();
1296
+
1297
+ await runWalk(
1298
+ {
1299
+ isOnline: false,
1300
+ responseTimeInMs: 0,
1301
+ failureCause: "Device did not respond",
1302
+ },
1303
+ { isOnline: false },
1304
+ );
1305
+
1306
+ /*
1307
+ * For a probe-polled device this exact walk MUST write (the attempt has
1308
+ * to be recorded); for a monitor-backed one the attempt is meaningless
1309
+ * and an empty payload is correctly skipped.
1310
+ */
1311
+ expect(deviceUpdateSpy).not.toHaveBeenCalled();
1312
+ expect(warn).toHaveBeenCalledTimes(1);
1313
+ });
1314
+
1315
+ /*
1316
+ * The ping-mode NULLs are health writes too: a monitor-backed device's
1317
+ * interface counts belong to whatever last wrote them, not to a poll that
1318
+ * should never have reached it.
1319
+ */
1320
+ test("a ping-only poll of a monitor-backed device writes nothing - not even the NULLs - and warns once", async () => {
1321
+ mockServices([], {
1322
+ monitoringMethod: NetworkDeviceMonitoringMethod.Monitor,
1323
+ });
1324
+ const warn: jest.SpyInstance = spyWarn();
1325
+
1326
+ await runPingOnlyPoll({ isOnline: true });
1327
+
1328
+ expect(deviceUpdateSpy).not.toHaveBeenCalled();
1329
+ expect(warn).toHaveBeenCalledTimes(1);
1330
+ });
1331
+
1332
+ test("selects monitoringMethod on the device read, or the guard can never fire", async () => {
1333
+ mockServices();
1334
+
1335
+ await runWalk();
1336
+
1337
+ const findArgs: { select?: Record<string, boolean> } = deviceFindSpy.mock
1338
+ .calls[0]![0] as unknown as { select?: Record<string, boolean> };
1339
+
1340
+ expect(findArgs.select?.["monitoringMethod"]).toBe(true);
1341
+ });
1342
+
1343
+ test("an SNMP walk is unchanged: every poll and interface column is written and nothing warns", async () => {
1344
+ mockServices([], {
1345
+ monitoringMethod: NetworkDeviceMonitoringMethod.Probe,
1346
+ });
1347
+ const warn: jest.SpyInstance = spyWarn();
1348
+
1349
+ await runWalk({
1350
+ interfaces: [
1351
+ walkedInterface({ interfaceIndex: 1, isOperationallyUp: true }),
1352
+ walkedInterface({ interfaceIndex: 2, isOperationallyUp: false }),
1353
+ ],
1354
+ });
1355
+
1356
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
1357
+
1358
+ expect(update["lastPolledAt"]).toEqual(NOW);
1359
+ expect(update["isReachable"]).toBe(true);
1360
+ expect(update["lastSeenAt"]).toEqual(NOW);
1361
+ expect(update["isSnmpReachable"]).toBe(true);
1362
+ expect(update["lastSnmpSeenAt"]).toEqual(NOW);
1363
+ expect(update["interfacesTotal"]).toBe(2);
1364
+ expect(update["interfacesUp"]).toBe(1);
1365
+ expect(update["interfacesDown"]).toBe(1);
1366
+ expect(warn).not.toHaveBeenCalled();
1367
+ });
1368
+
1369
+ test("a row with no monitoringMethod at all (written before the column existed) is walked as SNMP", async () => {
1370
+ // The default device carries no monitoringMethod, exactly like a legacy row.
1371
+ mockServices();
1372
+ const warn: jest.SpyInstance = spyWarn();
1373
+
1374
+ await runWalk();
1375
+
1376
+ const update: DeviceUpdatePayload = deviceUpdatePayload();
1377
+
1378
+ expect(update["isReachable"]).toBe(true);
1379
+ expect(update["lastPolledAt"]).toEqual(NOW);
1380
+ expect(warn).not.toHaveBeenCalled();
1381
+ });
1382
+ });
@@ -47,6 +47,8 @@ const NOW: Date = OneUptimeDate.fromString("2026-08-27T12:00:00.000Z");
47
47
  /** A device row as it exists in Postgres, before any grouping. */
48
48
  interface DeviceRow {
49
49
  monitorStatusIsOffline: boolean | undefined;
50
+ // Raw column value: null for rows written before it existed.
51
+ monitoringMethod: string | null;
50
52
  isReachable: boolean | null;
51
53
  lastPolledAt: Date | null;
52
54
  lastSeenAt: Date | null;
@@ -94,7 +96,7 @@ function bucketFor(
94
96
  // The bucket key stands for the status; the flag is passed alongside it.
95
97
  monitorStatusId:
96
98
  device.monitorStatusIsOffline === undefined ? null : "status-id",
97
- monitoringMethod: null,
99
+ monitoringMethod: device.monitoringMethod,
98
100
  isReachable: device.isReachable,
99
101
  hasBeenPolled: device.lastPolledAt !== null,
100
102
  hasBeenSeen: device.lastSeenAt !== null,
@@ -116,6 +118,7 @@ function toClassifierInput(device: DeviceRow): DeviceHealthStateInput {
116
118
  lastPolledAt: device.lastPolledAt,
117
119
  lastSeenAt: device.lastSeenAt,
118
120
  pollingIntervalInMinutes: device.pollingIntervalInMinutes,
121
+ monitoringMethod: device.monitoringMethod,
119
122
  interfacesDown: device.interfacesDown,
120
123
  };
121
124
  }
@@ -156,6 +159,7 @@ function everyDistinguishableDevice(): Array<DeviceRow> {
156
159
  for (const interfacesDown of interfaceCounts) {
157
160
  rows.push({
158
161
  monitorStatusIsOffline: monitorStatusIsOffline,
162
+ monitoringMethod: null,
159
163
  isReachable: isReachable,
160
164
  lastPolledAt: lastPolledAt,
161
165
  lastSeenAt: lastSeenAt,
@@ -169,15 +173,32 @@ function everyDistinguishableDevice(): Array<DeviceRow> {
169
173
  }
170
174
  }
171
175
 
172
- return rows;
176
+ /*
177
+ * Doubled across the monitoring method last, so every combination above
178
+ * exists once as an SNMP row and once as a monitor-backed row holding the
179
+ * SAME poll columns — which is exactly the shape a device switched from
180
+ * SNMP to Monitor has, and the shape that must classify differently.
181
+ */
182
+ const monitoringMethods: Array<string | null> = [null, "Monitor"];
183
+
184
+ return monitoringMethods.flatMap(
185
+ (monitoringMethod: string | null): Array<DeviceRow> => {
186
+ return rows.map((row: DeviceRow): DeviceRow => {
187
+ return { ...row, monitoringMethod: monitoringMethod };
188
+ });
189
+ },
190
+ );
173
191
  }
174
192
 
175
193
  describe("bucketing a device loses nothing the classifier reads", () => {
176
194
  const devices: Array<DeviceRow> = everyDistinguishableDevice();
177
195
 
178
196
  test("the matrix is big enough to be worth calling exhaustive", () => {
179
- // 3 monitor states x 3 reachability x 4 x 4 timestamps x 3 intervals x 2.
180
- expect(devices).toHaveLength(3 * 3 * 4 * 4 * 3 * 2);
197
+ /*
198
+ * 3 monitor states x 3 reachability x 4 x 4 timestamps x 3 intervals x
199
+ * 2 interface counts x 2 monitoring methods.
200
+ */
201
+ expect(devices).toHaveLength(3 * 3 * 4 * 4 * 3 * 2 * 2);
181
202
  });
182
203
 
183
204
  test("every device classifies the same through its bucket as directly", () => {
@@ -316,6 +337,7 @@ describe("bucketing a device loses nothing the classifier reads", () => {
316
337
  lastPolledAt: device.lastPolledAt,
317
338
  lastSeenAt: device.lastSeenAt,
318
339
  pollingIntervalInMinutes: device.pollingIntervalInMinutes,
340
+ monitoringMethod: device.monitoringMethod,
319
341
  };
320
342
 
321
343
  const direct: string | null = SiteStatusRollupUtil.worstStatus({
@@ -431,12 +453,16 @@ describe("bucketing a device loses nothing the classifier reads", () => {
431
453
  });
432
454
 
433
455
  /*
434
- * `deviceHealthState` must not start reading the monitoring method: it does
435
- * not today, and a bucket that carried it into the input would change every
436
- * monitor-backed device's verdict on the site cards without touching a
437
- * single line of the classifier.
456
+ * The bucket carries the monitoring method INTO the classifier input, and
457
+ * the classifier reads it (issue #3562). An earlier revision pinned the
458
+ * opposite that carrying it changed nothing which held only while a
459
+ * monitor-backed row had NULL in every poll column. The server now mirrors
460
+ * the bound monitor into `isReachable`, and a device switched over from
461
+ * SNMP keeps its old lastSeenAt until the switch-over clears it; a
462
+ * classifier that ignored the method would read either as a poll verdict
463
+ * and disagree with the device list under the card.
438
464
  */
439
- test("carrying the monitoring method does not change the health verdict", () => {
465
+ test("the monitoring method is carried into the input and decides an unstamped bucket", () => {
440
466
  const base: DeviceHealthGroup = {
441
467
  siteId: null,
442
468
  monitorStatusId: null,
@@ -455,17 +481,115 @@ describe("bucketing a device loses nothing the classifier reads", () => {
455
481
  monitoringMethod: "Monitor",
456
482
  };
457
483
 
484
+ expect(
485
+ deviceHealthInputForGroup({ group: base, now: NOW }).monitoringMethod,
486
+ ).toBeNull();
487
+ expect(
488
+ deviceHealthInputForGroup({ group: withMethod, now: NOW })
489
+ .monitoringMethod,
490
+ ).toBe("Monitor");
491
+
492
+ // A mirrored, unstamped outcome on an SNMP row is a poll verdict...
493
+ expect(
494
+ deviceHealthState(
495
+ deviceHealthInputForGroup({ group: base, now: NOW }),
496
+ NOW,
497
+ ),
498
+ ).toBe("healthy");
499
+ // ...and on a monitor-backed row it is not a verdict at all.
458
500
  expect(
459
501
  deviceHealthState(
460
502
  deviceHealthInputForGroup({ group: withMethod, now: NOW }),
461
503
  NOW,
462
504
  ),
463
- ).toBe(
505
+ ).toBe("unknown");
506
+ // A stamp is, on either.
507
+ expect(
464
508
  deviceHealthState(
465
- deviceHealthInputForGroup({ group: base, now: NOW }),
509
+ deviceHealthInputForGroup({
510
+ group: withMethod,
511
+ monitorStatusIsOffline: false,
512
+ now: NOW,
513
+ }),
466
514
  NOW,
467
515
  ),
468
- );
516
+ ).toBe("healthy");
517
+ expect(
518
+ deviceHealthState(
519
+ deviceHealthInputForGroup({
520
+ group: withMethod,
521
+ monitorStatusIsOffline: true,
522
+ now: NOW,
523
+ }),
524
+ NOW,
525
+ ),
526
+ ).toBe("down");
527
+ });
528
+
529
+ /*
530
+ * The rollup reads the same buckets through its own builder, and the site
531
+ * it colours is the card the tally above prints on — so the two builders
532
+ * have to carry the method identically or the card's counts and its
533
+ * colour describe different fleets.
534
+ */
535
+ test("the rollup state carries the monitoring method the same way", () => {
536
+ const leftovers: DeviceHealthGroup = {
537
+ siteId: null,
538
+ monitorStatusId: null,
539
+ monitoringMethod: null,
540
+ isReachable: null,
541
+ hasBeenPolled: false,
542
+ hasBeenSeen: true,
543
+ isStale: true,
544
+ hasDownInterfaces: false,
545
+ deviceCount: 1,
546
+ interfacesDownTotal: 0,
547
+ };
548
+ const operational: { monitorStatusId: string; priority: number } = {
549
+ monitorStatusId: "operational",
550
+ priority: 1,
551
+ };
552
+ const offline: { monitorStatusId: string; priority: number } = {
553
+ monitorStatusId: "offline",
554
+ priority: 3,
555
+ };
556
+
557
+ expect(
558
+ deviceRollupStateForGroup({ group: leftovers, now: NOW })
559
+ .monitoringMethod,
560
+ ).toBeNull();
561
+ expect(
562
+ deviceRollupStateForGroup({
563
+ group: { ...leftovers, monitoringMethod: "Monitor" },
564
+ now: NOW,
565
+ }).monitoringMethod,
566
+ ).toBe("Monitor");
567
+
568
+ // Stale leftovers on an SNMP row vote offline (the legacy branch)...
569
+ expect(
570
+ SiteStatusRollupUtil.worstStatus({
571
+ deviceStates: [
572
+ deviceRollupStateForGroup({ group: leftovers, now: NOW }),
573
+ ],
574
+ operationalStatus: operational,
575
+ offlineStatus: offline,
576
+ now: NOW,
577
+ }),
578
+ ).toBe("offline");
579
+ // ...and on a monitor-backed row they are not a vote at all.
580
+ expect(
581
+ SiteStatusRollupUtil.worstStatus({
582
+ deviceStates: [
583
+ deviceRollupStateForGroup({
584
+ group: { ...leftovers, monitoringMethod: "Monitor" },
585
+ now: NOW,
586
+ }),
587
+ ],
588
+ operationalStatus: operational,
589
+ offlineStatus: offline,
590
+ now: NOW,
591
+ }),
592
+ ).toBeNull();
469
593
  });
470
594
  });
471
595