@oneuptime/common 11.6.1 → 11.7.0

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 (420) hide show
  1. package/Models/AnalyticsModels/Index.ts +4 -0
  2. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  3. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  4. package/Models/AnalyticsModels/SloHistory.ts +243 -0
  5. package/Models/DatabaseModels/Index.ts +20 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  8. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  9. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  10. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  11. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  13. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  14. package/Models/DatabaseModels/ServiceLevelObjective.ts +1115 -0
  15. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  16. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  17. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.ts +30 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  25. package/Server/Services/AnalyticsDatabaseService.ts +25 -9
  26. package/Server/Services/Index.ts +24 -0
  27. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  28. package/Server/Services/MetricService.ts +21 -2
  29. package/Server/Services/MonitorService.ts +22 -0
  30. package/Server/Services/NetworkDeviceService.ts +438 -2
  31. package/Server/Services/NetworkEndpointService.ts +414 -0
  32. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  33. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  34. package/Server/Services/NetworkSiteService.ts +1254 -0
  35. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  36. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  37. package/Server/Services/ProjectService.ts +122 -2
  38. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  39. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  40. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  41. package/Server/Services/ServiceLevelObjectiveService.ts +685 -0
  42. package/Server/Services/SloHistoryService.ts +101 -0
  43. package/Server/Services/UserNotificationSettingService.ts +37 -0
  44. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  45. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  46. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  47. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
  48. package/Server/Utils/Memory.ts +9 -1
  49. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  50. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  51. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  52. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  53. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  54. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  55. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  56. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  57. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  58. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  59. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  60. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  61. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  62. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  63. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  64. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  65. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  66. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  67. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  68. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  69. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  70. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  72. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
  73. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  74. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  75. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  76. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  77. package/Tests/Server/Utils/Memory.test.ts +213 -0
  78. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  79. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  80. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  81. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  82. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  83. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  84. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  85. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  86. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  87. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  88. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  89. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  90. package/Tests/Server/Utils/Stream.test.ts +87 -0
  91. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  92. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  93. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  94. package/Tests/Types/Email.test.ts +198 -0
  95. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  96. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  97. package/Tests/Types/Monitor/MonitorCriteria.test.ts +155 -0
  98. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +465 -0
  99. package/Tests/Types/Monitor/MonitorStep.test.ts +183 -0
  100. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  101. package/Tests/Types/Monitor/MonitorSteps.test.ts +183 -0
  102. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  103. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  104. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  105. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  106. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  107. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  108. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  109. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  110. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  111. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  112. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  113. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  114. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  115. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  116. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  117. package/Tests/Utils/Base64.test.ts +51 -0
  118. package/Tests/Utils/Boolean.test.ts +76 -0
  119. package/Tests/Utils/Crypto.test.ts +48 -0
  120. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  121. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  122. package/Tests/Utils/Enum.test.ts +54 -0
  123. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  124. package/Tests/Utils/Memory.test.ts +44 -0
  125. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  126. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  127. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  128. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  129. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  130. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  131. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  132. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  133. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  134. package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +124 -0
  135. package/Tests/Utils/Slo/SloDuration.test.ts +148 -0
  136. package/Tests/Utils/Slo/SloHealth.test.ts +334 -0
  137. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  138. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  139. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  140. package/Tests/Utils/TechStack.test.ts +50 -0
  141. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  142. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  143. package/Types/BaseDatabase/EqualTo.ts +9 -1
  144. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  145. package/Types/BaseDatabase/NotEqual.ts +9 -1
  146. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  147. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  148. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  149. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  150. package/Types/Email/EmailTemplateType.ts +2 -0
  151. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  152. package/Types/Monitor/CriteriaFilter.ts +9 -0
  153. package/Types/Monitor/MonitorStep.ts +5 -8
  154. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  155. package/Types/Monitor/MonitorType.ts +15 -5
  156. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  157. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  158. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  159. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  160. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  161. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  162. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  163. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  164. package/Types/Permission.ts +449 -0
  165. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  166. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  167. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  168. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  169. package/Types/Telemetry/ServiceType.ts +1 -0
  170. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  171. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  172. package/UI/Components/List/List.tsx +8 -0
  173. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  174. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  175. package/UI/Components/Navbar/NavBar.tsx +16 -2
  176. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  177. package/UI/Utils/Navigation.ts +10 -0
  178. package/UI/Utils/TableFilterUrlState.ts +204 -17
  179. package/UI/Utils/TableViewUrlState.ts +165 -0
  180. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  181. package/Utils/Dashboard/Components/Index.ts +7 -0
  182. package/Utils/IpCanonicalUtil.ts +134 -0
  183. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  184. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  185. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  186. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  187. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  188. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  189. package/Utils/Slo/SloBurnRateRuleState.ts +91 -0
  190. package/Utils/Slo/SloDuration.ts +165 -0
  191. package/Utils/Slo/SloEvaluation.ts +22 -0
  192. package/Utils/Slo/SloHealth.ts +302 -0
  193. package/Utils/Slo/SloStatusColor.ts +54 -0
  194. package/Utils/Slo/SloUtil.ts +637 -0
  195. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  196. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  197. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  198. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  199. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  200. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  201. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  202. package/build/dist/Models/AnalyticsModels/SloHistory.js +218 -0
  203. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  204. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  205. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  207. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  209. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  211. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  212. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  213. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  214. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  215. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  216. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  217. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  218. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  219. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  220. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  221. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  222. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1134 -0
  223. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  224. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  225. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  226. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  227. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  228. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  229. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js +21 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js.map +1 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  244. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
  245. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  246. package/build/dist/Server/Services/Index.js +24 -0
  247. package/build/dist/Server/Services/Index.js.map +1 -1
  248. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  249. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  250. package/build/dist/Server/Services/MetricService.js +21 -3
  251. package/build/dist/Server/Services/MetricService.js.map +1 -1
  252. package/build/dist/Server/Services/MonitorService.js +19 -0
  253. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  254. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  255. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  256. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  257. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  258. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  259. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  260. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  261. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  262. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  263. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  264. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  265. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  266. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  267. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  268. package/build/dist/Server/Services/ProjectService.js +98 -2
  269. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  270. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  271. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  272. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  273. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  274. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  275. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  276. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +588 -0
  277. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  278. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  279. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  280. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  281. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  282. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  283. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  284. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  285. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  286. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  287. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  288. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
  289. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  290. package/build/dist/Server/Utils/Memory.js +9 -1
  291. package/build/dist/Server/Utils/Memory.js.map +1 -1
  292. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  293. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  294. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  295. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  296. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  297. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  298. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  299. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  300. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  301. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  302. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  303. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  304. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  305. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  306. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  307. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  308. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  309. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  310. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  311. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  312. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  313. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  314. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  315. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  316. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  317. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  318. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  319. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  320. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  321. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  322. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  323. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  324. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  325. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  326. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  327. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  328. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  329. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  330. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  331. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  332. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  333. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  334. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  335. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  336. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  337. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  338. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  339. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  340. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  341. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  342. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  343. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  344. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  345. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  346. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  347. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  348. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  349. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  350. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  351. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  352. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  353. package/build/dist/Types/Permission.js +409 -0
  354. package/build/dist/Types/Permission.js.map +1 -1
  355. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  356. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  357. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  358. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  359. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  360. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  361. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  362. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  363. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  364. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  365. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  366. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  367. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  368. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  369. package/build/dist/UI/Components/List/List.js +1 -1
  370. package/build/dist/UI/Components/List/List.js.map +1 -1
  371. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  372. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  373. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  374. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  375. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  376. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  377. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  378. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  379. package/build/dist/UI/Utils/Navigation.js +9 -0
  380. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  381. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  382. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  383. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  384. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  385. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  386. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  387. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  388. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  389. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  390. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  391. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  392. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  393. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  394. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  395. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  396. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  397. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  398. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  399. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  400. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  401. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  402. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  403. package/build/dist/Utils/Slo/SloBurnRateRuleState.js +35 -0
  404. package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -0
  405. package/build/dist/Utils/Slo/SloDuration.js +87 -0
  406. package/build/dist/Utils/Slo/SloDuration.js.map +1 -0
  407. package/build/dist/Utils/Slo/SloEvaluation.js +21 -0
  408. package/build/dist/Utils/Slo/SloEvaluation.js.map +1 -0
  409. package/build/dist/Utils/Slo/SloHealth.js +179 -0
  410. package/build/dist/Utils/Slo/SloHealth.js.map +1 -0
  411. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  412. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  413. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  414. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  415. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  416. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  417. package/package.json +2 -2
  418. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  419. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  420. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -14,6 +14,7 @@ import MonitorOwnerTeamService from "./MonitorOwnerTeamService";
14
14
  import MonitorOwnerUserService from "./MonitorOwnerUserService";
15
15
  import MonitorProbeService from "./MonitorProbeService";
16
16
  import MonitorStatusService from "./MonitorStatusService";
17
+ import NetworkSiteService from "./NetworkSiteService";
17
18
  import MonitorStatusTimelineService, {
18
19
  MONITOR_STATUS_SAME_AS_PREVIOUS_ERROR_MESSAGE,
19
20
  MONITOR_STATUS_TIMELINE_LOCK_ERROR_MESSAGE,
@@ -1745,6 +1746,27 @@ ${createdItem.description?.trim() || "No description provided."}
1745
1746
  monitorId: monitorId,
1746
1747
  });
1747
1748
  }
1749
+
1750
+ /*
1751
+ * Bridge to the network-site rollup engine: stamp the NetworkDevices
1752
+ * these monitors poll and refresh their sites' worst-of status.
1753
+ * Resilient by contract - a rollup failure can never break a monitor
1754
+ * status change (onMonitorStatusChanged also catches internally).
1755
+ */
1756
+ try {
1757
+ await NetworkSiteService.onMonitorStatusChanged({
1758
+ projectId: projectId,
1759
+ monitorIds: monitorIds,
1760
+ monitorStatusId: monitorStatusId,
1761
+ });
1762
+ } catch (err) {
1763
+ logger.error(
1764
+ `changeMonitorStatus: failed to update network site rollups: ${err}`,
1765
+ {
1766
+ projectId: projectId.toString(),
1767
+ } as LogAttributes,
1768
+ );
1769
+ }
1748
1770
  }
1749
1771
 
1750
1772
  /*
@@ -1,20 +1,110 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import NetworkDeviceLabelRuleEngineService from "./NetworkDeviceLabelRuleEngineService";
3
3
  import NetworkDeviceOwnerRuleEngineService from "./NetworkDeviceOwnerRuleEngineService";
4
+ import NetworkSiteAssignmentRuleService from "./NetworkSiteAssignmentRuleService";
5
+ import NetworkSiteService from "./NetworkSiteService";
4
6
  import Model from "../../Models/DatabaseModels/NetworkDevice";
5
- import { OnCreate } from "../Types/Database/Hooks";
7
+ import NetworkSite from "../../Models/DatabaseModels/NetworkSite";
8
+ import NetworkSiteAssignmentRule from "../../Models/DatabaseModels/NetworkSiteAssignmentRule";
9
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
10
+ import CreateBy from "../Types/Database/CreateBy";
11
+ import UpdateBy from "../Types/Database/UpdateBy";
12
+ import Query from "../Types/Database/Query";
6
13
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
7
14
  import logger, { LogAttributes } from "../Utils/Logger";
15
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
16
+ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
17
+ import BadDataException from "../../Types/Exception/BadDataException";
18
+ import ObjectID from "../../Types/ObjectID";
19
+ import OneUptimeDate from "../../Types/Date";
20
+ import CidrMatchUtil from "../../Utils/NetworkSite/CidrMatchUtil";
21
+ import { EntityManager } from "typeorm";
8
22
 
9
23
  export class Service extends DatabaseService<Model> {
10
24
  public constructor() {
11
25
  super(Model);
12
26
  }
13
27
 
28
+ /*
29
+ * The FK behind siteId only requires the NetworkSite row to exist, not that
30
+ * it belongs to the device's project. Without this check a tenant can point
31
+ * a device at another project's site and make onUpdateSuccess drive rollup
32
+ * writes there under root props. Mirrors the parentSiteId guard in
33
+ * NetworkSiteService.onBeforeCreate.
34
+ */
35
+ private async assertSiteBelongsToProject(data: {
36
+ siteId: ObjectID;
37
+ projectId: ObjectID | undefined;
38
+ }): Promise<void> {
39
+ if (!data.projectId) {
40
+ return;
41
+ }
42
+
43
+ const site: NetworkSite | null = await NetworkSiteService.findOneById({
44
+ id: data.siteId,
45
+ select: {
46
+ _id: true,
47
+ projectId: true,
48
+ },
49
+ props: {
50
+ isRoot: true,
51
+ },
52
+ });
53
+
54
+ if (!site) {
55
+ throw new BadDataException("Network site not found.");
56
+ }
57
+
58
+ if (
59
+ site.projectId &&
60
+ site.projectId.toString() !== data.projectId.toString()
61
+ ) {
62
+ throw new BadDataException(
63
+ "Network site must belong to the same project.",
64
+ );
65
+ }
66
+ }
67
+
68
+ /*
69
+ * onBeforeUpdate runs before DatabaseService permission-checks the query,
70
+ * so reading the raw client query as root would hand the hook rows from
71
+ * other projects. Re-apply the caller's tenant here.
72
+ */
73
+ private scopeQueryToCallerTenant(
74
+ query: Query<Model>,
75
+ props: DatabaseCommonInteractionProps,
76
+ ): Query<Model> {
77
+ if (props.isRoot || !props.tenantId) {
78
+ return query;
79
+ }
80
+
81
+ return {
82
+ ...query,
83
+ projectId: props.tenantId,
84
+ };
85
+ }
86
+
87
+ @CaptureSpan()
88
+ protected override async onBeforeCreate(
89
+ createBy: CreateBy<Model>,
90
+ ): Promise<OnCreate<Model>> {
91
+ if (createBy.data.siteId) {
92
+ await this.assertSiteBelongsToProject({
93
+ siteId: createBy.data.siteId,
94
+ projectId: createBy.data.projectId,
95
+ });
96
+ }
97
+
98
+ return { createBy, carryForward: null };
99
+ }
100
+
14
101
  /*
15
102
  * Owner/label rules fire whenever a device is created — manually or via
16
103
  * subnet discovery import. Applied out-of-band: rule failures must never
17
- * fail device creation.
104
+ * fail device creation. Site auto-assignment rides the same chain: a
105
+ * device created without a site is matched against the project's
106
+ * NetworkSiteAssignmentRules, and a device created directly into a site
107
+ * refreshes that site's rollup.
18
108
  */
19
109
  @CaptureSpan()
20
110
  protected override async onCreateSuccess(
@@ -33,6 +123,15 @@ export class Service extends DatabaseService<Model> {
33
123
  createdItem,
34
124
  );
35
125
  })
126
+ .then(async () => {
127
+ if (createdItem.siteId) {
128
+ await NetworkSiteService.recomputeRollupForSiteAndAncestors(
129
+ createdItem.siteId,
130
+ );
131
+ } else {
132
+ await this.applySiteAssignmentRulesToDevice(createdItem.id!);
133
+ }
134
+ })
36
135
  .catch((error: Error) => {
37
136
  logger.error(
38
137
  `Error applying network device rules in NetworkDeviceService.onCreateSuccess: ${error}`,
@@ -45,6 +144,343 @@ export class Service extends DatabaseService<Model> {
45
144
  }
46
145
  return createdItem;
47
146
  }
147
+
148
+ /*
149
+ * Capture the previous site of every matched device when an update
150
+ * touches siteId, so onUpdateSuccess can refresh the OLD site's rollup
151
+ * as well as the new one.
152
+ */
153
+ @CaptureSpan()
154
+ protected override async onBeforeUpdate(
155
+ updateBy: UpdateBy<Model>,
156
+ ): Promise<OnUpdate<Model>> {
157
+ const dataKeys: Array<string> = Object.keys(updateBy.data || {});
158
+
159
+ if (!dataKeys.includes("siteId")) {
160
+ return { updateBy, carryForward: null };
161
+ }
162
+
163
+ const previousDevices: Array<Model> = await this.findBy({
164
+ query: this.scopeQueryToCallerTenant(updateBy.query, updateBy.props),
165
+ select: {
166
+ _id: true,
167
+ projectId: true,
168
+ siteId: true,
169
+ },
170
+ limit: LIMIT_MAX,
171
+ skip: 0,
172
+ props: {
173
+ isRoot: true,
174
+ },
175
+ });
176
+
177
+ const newSiteIdValue: unknown = (updateBy.data as any)["siteId"];
178
+
179
+ if (newSiteIdValue) {
180
+ const newSiteId: ObjectID = new ObjectID(newSiteIdValue.toString());
181
+ const checkedProjectIds: Set<string> = new Set();
182
+
183
+ for (const previousDevice of previousDevices) {
184
+ if (
185
+ !previousDevice.projectId ||
186
+ checkedProjectIds.has(previousDevice.projectId.toString())
187
+ ) {
188
+ continue;
189
+ }
190
+ checkedProjectIds.add(previousDevice.projectId.toString());
191
+
192
+ await this.assertSiteBelongsToProject({
193
+ siteId: newSiteId,
194
+ projectId: previousDevice.projectId,
195
+ });
196
+ }
197
+ }
198
+
199
+ return {
200
+ updateBy,
201
+ carryForward: {
202
+ previousDevices: previousDevices,
203
+ },
204
+ };
205
+ }
206
+
207
+ /*
208
+ * Site maintenance after device updates. Resilient by design: a rollup
209
+ * or rule-engine failure must never fail the device update itself.
210
+ */
211
+ @CaptureSpan()
212
+ protected override async onUpdateSuccess(
213
+ onUpdate: OnUpdate<Model>,
214
+ updatedItemIds: Array<ObjectID>,
215
+ ): Promise<OnUpdate<Model>> {
216
+ try {
217
+ const dataKeys: Array<string> = Object.keys(onUpdate.updateBy.data || {});
218
+
219
+ if (dataKeys.includes("siteId")) {
220
+ // Manual or rule-driven site change: refresh old + new site chains.
221
+ const affectedSiteIds: Map<string, ObjectID> = new Map();
222
+
223
+ const previousDevices: Array<Model> =
224
+ (onUpdate.carryForward?.previousDevices as Array<Model>) || [];
225
+
226
+ /*
227
+ * onUpdateSuccess runs even when the permission-scoped UPDATE matched
228
+ * nothing, so only devices the UPDATE actually touched may drive
229
+ * rollup writes.
230
+ */
231
+ const updatedIds: Set<string> = new Set(
232
+ updatedItemIds.map((id: ObjectID) => {
233
+ return id.toString();
234
+ }),
235
+ );
236
+
237
+ for (const previousDevice of previousDevices) {
238
+ if (
239
+ !previousDevice.id ||
240
+ !updatedIds.has(previousDevice.id.toString())
241
+ ) {
242
+ continue;
243
+ }
244
+
245
+ if (previousDevice.siteId) {
246
+ affectedSiteIds.set(
247
+ previousDevice.siteId.toString(),
248
+ previousDevice.siteId,
249
+ );
250
+ }
251
+ }
252
+
253
+ const newSiteIdValue: unknown = (onUpdate.updateBy.data as any)[
254
+ "siteId"
255
+ ];
256
+ if (newSiteIdValue && updatedItemIds.length > 0) {
257
+ const newSiteId: ObjectID = new ObjectID(newSiteIdValue.toString());
258
+ affectedSiteIds.set(newSiteId.toString(), newSiteId);
259
+ }
260
+
261
+ for (const siteId of affectedSiteIds.values()) {
262
+ await NetworkSiteService.recomputeRollupForSiteAndAncestors(siteId);
263
+ }
264
+ } else if (dataKeys.includes("hostname")) {
265
+ /*
266
+ * The device's address changed, so subnet/hostname rules may now
267
+ * resolve differently — re-evaluate each updated device.
268
+ */
269
+ for (const deviceId of updatedItemIds) {
270
+ await this.applySiteAssignmentRulesToDevice(deviceId);
271
+ }
272
+ }
273
+ } catch (error) {
274
+ logger.error(
275
+ `Error in NetworkDeviceService.onUpdateSuccess site maintenance: ${error}`,
276
+ );
277
+ }
278
+
279
+ return onUpdate;
280
+ }
281
+
282
+ /*
283
+ * Matches one device against the project's NetworkSiteAssignmentRules
284
+ * (highest priority wins) and assigns the winning site. The assignment
285
+ * goes through updateOneById so onUpdateSuccess refreshes the rollups of
286
+ * both the old and the new site.
287
+ */
288
+ @CaptureSpan()
289
+ public async applySiteAssignmentRulesToDevice(
290
+ deviceId: ObjectID,
291
+ ): Promise<void> {
292
+ const device: Model | null = await this.findOneById({
293
+ id: deviceId,
294
+ select: {
295
+ _id: true,
296
+ projectId: true,
297
+ siteId: true,
298
+ hostname: true,
299
+ sysName: true,
300
+ },
301
+ props: {
302
+ isRoot: true,
303
+ },
304
+ });
305
+
306
+ if (!device || !device.id || !device.projectId) {
307
+ return;
308
+ }
309
+
310
+ const rules: Array<NetworkSiteAssignmentRule> =
311
+ await NetworkSiteAssignmentRuleService.findBy({
312
+ query: {
313
+ projectId: device.projectId,
314
+ },
315
+ select: {
316
+ _id: true,
317
+ siteId: true,
318
+ subnetCidr: true,
319
+ hostnamePattern: true,
320
+ priority: true,
321
+ createdAt: true,
322
+ },
323
+ limit: LIMIT_MAX,
324
+ skip: 0,
325
+ props: {
326
+ isRoot: true,
327
+ },
328
+ });
329
+
330
+ if (rules.length === 0) {
331
+ return;
332
+ }
333
+
334
+ /*
335
+ * The device's hostname column stores an IP address or a DNS name; pass
336
+ * it as both — ipInCidr safely rejects non-IP strings.
337
+ */
338
+ const winner: NetworkSiteAssignmentRule | null = CidrMatchUtil.pickRule(
339
+ rules,
340
+ {
341
+ ip: device.hostname,
342
+ hostname: device.hostname,
343
+ sysName: device.sysName,
344
+ },
345
+ );
346
+
347
+ if (!winner || !winner.siteId) {
348
+ return;
349
+ }
350
+
351
+ if (
352
+ device.siteId &&
353
+ device.siteId.toString() === winner.siteId.toString()
354
+ ) {
355
+ return;
356
+ }
357
+
358
+ await this.updateOneById({
359
+ id: device.id,
360
+ data: {
361
+ siteId: winner.siteId,
362
+ },
363
+ props: {
364
+ isRoot: true,
365
+ },
366
+ });
367
+ }
368
+
369
+ /*
370
+ * Atomically claims the devices this probe should poll now and advances
371
+ * each device's nextPollAt by its own polling interval — the device-owned
372
+ * twin of MonitorProbeService.claimMonitorProbesForProbing. FOR UPDATE
373
+ * SKIP LOCKED keeps horizontally-scaled probe ingest instances from
374
+ * handing the same device to two pollers.
375
+ *
376
+ * Suspended projects are skipped for the same reason monitor claiming
377
+ * skips them; archived devices keep polling on purpose ("archived devices
378
+ * keep collecting telemetry").
379
+ */
380
+ @CaptureSpan()
381
+ public async claimDevicesForPolling(data: {
382
+ probeId: ObjectID;
383
+ limit: number;
384
+ }): Promise<Array<ObjectID>> {
385
+ const currentDate: Date = OneUptimeDate.getCurrentDate();
386
+
387
+ const claimedIds: Array<ObjectID> = await this.executeTransaction(
388
+ async (transactionalEntityManager: EntityManager) => {
389
+ const selectQuery: string = `
390
+ SELECT nd."_id", nd."pollingIntervalInMinutes"
391
+ FROM "NetworkDevice" nd
392
+ INNER JOIN "Project" p ON nd."projectId" = p."_id"
393
+ WHERE nd."probeId" = $1
394
+ AND nd."isPollingEnabled" = true
395
+ AND nd."deletedAt" IS NULL
396
+ AND nd."hostname" IS NOT NULL
397
+ AND (nd."nextPollAt" IS NULL OR nd."nextPollAt" <= $2)
398
+ AND p."deletedAt" IS NULL
399
+ AND (p."paymentProviderSubscriptionStatus" IS NULL
400
+ OR p."paymentProviderSubscriptionStatus" IN ('active', 'trialing'))
401
+ AND (p."paymentProviderMeteredSubscriptionStatus" IS NULL
402
+ OR p."paymentProviderMeteredSubscriptionStatus" IN ('active', 'trialing'))
403
+ ORDER BY nd."nextPollAt" ASC NULLS FIRST
404
+ LIMIT $3
405
+ FOR UPDATE OF nd SKIP LOCKED
406
+ `;
407
+
408
+ const selectedRows: Array<{
409
+ _id: string;
410
+ pollingIntervalInMinutes: number | null;
411
+ }> = await transactionalEntityManager.query(selectQuery, [
412
+ data.probeId.toString(),
413
+ currentDate,
414
+ data.limit,
415
+ ]);
416
+
417
+ if (selectedRows.length === 0) {
418
+ return [];
419
+ }
420
+
421
+ const ids: Array<string> = [];
422
+ const caseFragments: Array<string> = [];
423
+ const parameters: Array<string | Date> = [];
424
+ let parameterIndex: number = 1;
425
+
426
+ for (const row of selectedRows) {
427
+ /*
428
+ * Guard the interval: NULL falls back to the 5-minute default,
429
+ * and anything below 1 minute is clamped — a walk can take tens
430
+ * of seconds, so sub-minute schedules would only stack up.
431
+ */
432
+ const intervalInMinutes: number = Math.max(
433
+ row.pollingIntervalInMinutes || 5,
434
+ 1,
435
+ );
436
+
437
+ const nextPollAt: Date = OneUptimeDate.addRemoveMinutes(
438
+ currentDate,
439
+ intervalInMinutes,
440
+ );
441
+
442
+ ids.push(row._id);
443
+ /*
444
+ * ::timestamptz, not ::timestamp. node-postgres serialises a Date
445
+ * parameter as local wall-clock digits plus an explicit offset; a
446
+ * ::timestamp cast throws the offset away and the timestamptz
447
+ * column then re-reads those digits in the Postgres session's
448
+ * timezone. The claim query above compares nextPollAt without a
449
+ * cast (correctly, as timestamptz), so writing it as timestamp
450
+ * skews every schedule by the difference between the app's UTC
451
+ * offset and the database session timezone — devices then get
452
+ * re-polled on every cron tick, or not for hours.
453
+ */
454
+ caseFragments.push(
455
+ `WHEN $${parameterIndex} THEN $${parameterIndex + 1}::timestamptz`,
456
+ );
457
+ parameters.push(row._id, nextPollAt);
458
+ parameterIndex += 2;
459
+ }
460
+
461
+ const idPlaceholders: Array<string> = ids.map(
462
+ (_id: string, index: number) => {
463
+ return `$${parameterIndex + index}`;
464
+ },
465
+ );
466
+ parameters.push(...ids);
467
+
468
+ const updateQuery: string = `
469
+ UPDATE "NetworkDevice"
470
+ SET "nextPollAt" = CASE "_id" ${caseFragments.join(" ")} END
471
+ WHERE "_id" IN (${idPlaceholders.join(", ")})
472
+ `;
473
+
474
+ await transactionalEntityManager.query(updateQuery, parameters);
475
+
476
+ return ids.map((id: string) => {
477
+ return new ObjectID(id);
478
+ });
479
+ },
480
+ );
481
+
482
+ return claimedIds;
483
+ }
48
484
  }
49
485
 
50
486
  export default new Service();