@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
@@ -0,0 +1,691 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import DatabaseConfig from "../../DatabaseConfig";
11
+ import Semaphore from "../../Infrastructure/Semaphore";
12
+ import MailService from "../../Services/MailService";
13
+ import ProjectService from "../../Services/ProjectService";
14
+ import UserEmailService from "../../Services/UserEmailService";
15
+ import UserNotificationEmailRollupBatchService from "../../Services/UserNotificationEmailRollupBatchService";
16
+ import UserNotificationEmailRollupItemService from "../../Services/UserNotificationEmailRollupItemService";
17
+ import QueryHelper from "../../Types/Database/QueryHelper";
18
+ import PostgresErrorTranslator from "../Database/PostgresErrorTranslator";
19
+ import logger from "../Logger";
20
+ import CaptureSpan from "../Telemetry/CaptureSpan";
21
+ import { CLAIM_EPOCH_MINUTES, FLUSH_AFTER_MINUTES, MAX_BUCKETS_PER_TICK, MAX_DISCOVERY_PAGES_PER_TICK, MAX_ITEMS_PER_ROLLUP, MAX_ITEMS_SCANNED_PER_TICK, ROLLUP_JOB_NAME, ROLLUP_SEND_TIMEOUT_MS, ROLLUP_SWEEP_BUDGET_MS, ROLLUP_SWEEP_LOCK_NAMESPACE, ROLLUP_SWEEP_LOCK_TIMEOUT_MS, } from "./EmailRollupConstants";
22
+ import { buildRollupEmail } from "./EmailRollupRenderer";
23
+ import UserNotificationEmailRollupBatch, { RollupBatchStatus, } from "../../../Models/DatabaseModels/UserNotificationEmailRollupBatch";
24
+ import URL from "../../../Types/API/URL";
25
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
26
+ import ColumnLength from "../../../Types/Database/ColumnLength";
27
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
28
+ import OneUptimeDate from "../../../Types/Date";
29
+ import EmailTemplateType from "../../../Types/Email/EmailTemplateType";
30
+ import Text from "../../../Types/Text";
31
+ /*
32
+ * What one flush attempt ended up doing. Returned rather than logged so the
33
+ * sweep can count outcomes and a test can assert on them without reading log
34
+ * lines.
35
+ */
36
+ export var RollupFlushOutcome;
37
+ (function (RollupFlushOutcome) {
38
+ // Another replica, or an earlier flush in this same epoch, owns the bucket.
39
+ RollupFlushOutcome["Collision"] = "collision";
40
+ // The claim won but nothing was still pending by the time it stamped.
41
+ RollupFlushOutcome["Empty"] = "empty";
42
+ // Deliberately not sent: the address or the project went away.
43
+ RollupFlushOutcome["Skipped"] = "skipped";
44
+ RollupFlushOutcome["Sent"] = "sent";
45
+ RollupFlushOutcome["Failed"] = "failed";
46
+ })(RollupFlushOutcome || (RollupFlushOutcome = {}));
47
+ const MILLISECONDS_PER_MINUTE = 60 * 1000;
48
+ /*
49
+ * The batch table's statusMessage column is LongText, and a value longer than
50
+ * the column throws inside DatabaseService's own length check - which would
51
+ * turn "the send failed and we recorded why" into "the send failed and the
52
+ * recording of why also failed". Taken from the column length itself so the
53
+ * two can never drift apart.
54
+ */
55
+ const STATUS_MESSAGE_MAX_LENGTH = ColumnLength.LongText;
56
+ export default class EmailRollupFlushRunner {
57
+ /**
58
+ * The once-a-minute cron body: one sweep under a cross-replica lock.
59
+ *
60
+ * The lock is an OPTIMISATION, not a correctness mechanism. It exists so
61
+ * that N replicas do not all run the same scan every minute; the claim
62
+ * insert underneath it is what actually makes a rollup exactly-once. A held
63
+ * lock or an unreachable Redis therefore just skips the tick - the holder is
64
+ * covering the same work, and if nobody is, the next tick will.
65
+ */
66
+ static async runSweepUnderLock(options) {
67
+ let mutex = null;
68
+ try {
69
+ mutex = await Semaphore.lock({
70
+ key: ROLLUP_JOB_NAME,
71
+ namespace: ROLLUP_SWEEP_LOCK_NAMESPACE,
72
+ lockTimeout: ROLLUP_SWEEP_LOCK_TIMEOUT_MS,
73
+ acquireAttemptsLimit: 1,
74
+ });
75
+ }
76
+ catch (err) {
77
+ logger.debug(`${ROLLUP_JOB_NAME}: could not acquire the sweep lock; a sweep is already in flight (or Redis is unavailable). Skipping this run: ${err}`);
78
+ return null;
79
+ }
80
+ try {
81
+ return await EmailRollupFlushRunner.runSweep(options);
82
+ }
83
+ finally {
84
+ try {
85
+ await Semaphore.release(mutex);
86
+ }
87
+ catch (err) {
88
+ logger.error(`${ROLLUP_JOB_NAME}: error releasing the sweep lock: ${err}`);
89
+ }
90
+ }
91
+ }
92
+ /**
93
+ * One sweep: discover the due buckets oldest-first and flush each of them
94
+ * once. Never throws for one bucket's bad data - a bucket that fails is
95
+ * logged and the rest of the tick continues.
96
+ */
97
+ static async runSweep(options) {
98
+ const now = (options === null || options === void 0 ? void 0 : options.now) || OneUptimeDate.getCurrentDate();
99
+ const startMs = Date.now();
100
+ const cutoff = OneUptimeDate.addRemoveMinutes(now, FLUSH_AFTER_MINUTES * -1);
101
+ /*
102
+ * DISCOVERY IS BOUNDED, AND findBy IS THE POINT - not findAllBy.
103
+ * findAllBy pages to exhaustion, so a backlog spike would make this one
104
+ * query walk the entire pending table and blow the job's timeout part way
105
+ * through the loop, AFTER some buckets had already stamped their items but
106
+ * before they sent. An explicit limit means a backlog drains over several
107
+ * ticks instead, oldest first, which is also fairer across tenants.
108
+ *
109
+ * IT PAGES, THOUGH, AND THAT IS NOT AN OPTIMISATION. One page of
110
+ * MAX_ITEMS_SCANNED_PER_TICK rows sorted oldest-first can be entirely one
111
+ * saturated recipient: a single (project, user, address) with more than
112
+ * that many pending items would fill the page by itself, and every OTHER
113
+ * tenant's due rollup would be invisible for as long as the saturation
114
+ * lasted - a fleet-wide stall caused by one project, in exactly the storm
115
+ * this feature exists for. Paging past a hog costs a few extra indexed
116
+ * reads in a case that should never happen, and buys the guarantee that it
117
+ * cannot starve anybody.
118
+ */
119
+ const seen = new Set();
120
+ const buckets = [];
121
+ let itemsScanned = 0;
122
+ for (let page = 0; page < MAX_DISCOVERY_PAGES_PER_TICK; page++) {
123
+ const due = await UserNotificationEmailRollupItemService.findBy({
124
+ query: {
125
+ sentAt: QueryHelper.isNull(),
126
+ createdAt: QueryHelper.lessThanEqualTo(cutoff),
127
+ },
128
+ select: {
129
+ projectId: true,
130
+ userId: true,
131
+ toEmail: true,
132
+ createdAt: true,
133
+ },
134
+ sort: {
135
+ createdAt: SortOrder.Ascending,
136
+ },
137
+ limit: MAX_ITEMS_SCANNED_PER_TICK,
138
+ skip: page * MAX_ITEMS_SCANNED_PER_TICK,
139
+ props: {
140
+ isRoot: true,
141
+ },
142
+ });
143
+ itemsScanned += due.length;
144
+ /*
145
+ * Dedupe in JS, preserving first-seen order. The rows arrive
146
+ * oldest-first, so first-seen order IS oldest-bucket-first: the address
147
+ * that has been waiting longest is served first when the tick cannot
148
+ * serve everybody.
149
+ */
150
+ for (const item of due) {
151
+ if (!item.projectId || !item.userId || !item.toEmail) {
152
+ continue;
153
+ }
154
+ const key = `${item.projectId.toString()}|${item.userId.toString()}|${item.toEmail.toString()}`;
155
+ if (seen.has(key)) {
156
+ continue;
157
+ }
158
+ seen.add(key);
159
+ buckets.push({
160
+ projectId: item.projectId,
161
+ userId: item.userId,
162
+ toEmail: item.toEmail,
163
+ });
164
+ }
165
+ // A short page is the end of the pending set; there is nothing behind it.
166
+ if (due.length < MAX_ITEMS_SCANNED_PER_TICK) {
167
+ break;
168
+ }
169
+ // Enough work for this tick. The rest keeps until the next one.
170
+ if (buckets.length >= MAX_BUCKETS_PER_TICK) {
171
+ break;
172
+ }
173
+ }
174
+ const bucketsThisTick = buckets.slice(0, MAX_BUCKETS_PER_TICK);
175
+ const stats = {
176
+ now: now,
177
+ cutoff: cutoff,
178
+ itemsScanned: itemsScanned,
179
+ bucketsDue: buckets.length,
180
+ bucketsProcessed: 0,
181
+ sent: 0,
182
+ empty: 0,
183
+ skipped: 0,
184
+ failed: 0,
185
+ claimCollisions: 0,
186
+ errors: 0,
187
+ budgetExhausted: false,
188
+ };
189
+ for (const bucket of bucketsThisTick) {
190
+ if (Date.now() - startMs > ROLLUP_SWEEP_BUDGET_MS) {
191
+ stats.budgetExhausted = true;
192
+ logger.warn(`${ROLLUP_JOB_NAME}: sweep budget exhausted after ${stats.bucketsProcessed} of ${bucketsThisTick.length} bucket(s); the rest are picked up next tick.`);
193
+ break;
194
+ }
195
+ try {
196
+ const outcome = await EmailRollupFlushRunner.flushBucket(bucket, now);
197
+ stats.bucketsProcessed = stats.bucketsProcessed + 1;
198
+ if (outcome === RollupFlushOutcome.Sent) {
199
+ stats.sent = stats.sent + 1;
200
+ }
201
+ else if (outcome === RollupFlushOutcome.Empty) {
202
+ stats.empty = stats.empty + 1;
203
+ }
204
+ else if (outcome === RollupFlushOutcome.Skipped) {
205
+ stats.skipped = stats.skipped + 1;
206
+ }
207
+ else if (outcome === RollupFlushOutcome.Failed) {
208
+ stats.failed = stats.failed + 1;
209
+ }
210
+ else {
211
+ stats.claimCollisions = stats.claimCollisions + 1;
212
+ }
213
+ }
214
+ catch (err) {
215
+ /*
216
+ * PER-BUCKET ISOLATION. One tenant's unreadable row, or a claim that
217
+ * failed for a reason that is not a duplicate, must not cost every
218
+ * other address on this tick its rollup.
219
+ */
220
+ stats.errors = stats.errors + 1;
221
+ logger.error(err, {
222
+ projectId: bucket.projectId.toString(),
223
+ userId: bucket.userId.toString(),
224
+ });
225
+ }
226
+ }
227
+ return stats;
228
+ }
229
+ /**
230
+ * Claim one bucket's epoch, stamp its pending items, and send one rollup.
231
+ */
232
+ static async flushBucket(bucket, now) {
233
+ /*
234
+ * THE CLAIM KEY IS DERIVED FROM THE WALL CLOCK AND NOTHING ELSE.
235
+ *
236
+ * That is the whole reason the unique index is a real mutual exclusion:
237
+ * two replicas computing floor(now / epoch) at any instant inside the same
238
+ * epoch necessarily get the same value, so they necessarily collide.
239
+ * Derive it from the data instead - min(createdAt) of the pending rows,
240
+ * say - and two replicas reading slightly different snapshots would mint
241
+ * two different keys and both send.
242
+ *
243
+ * AND IT NEVER BLOCKS A LEGITIMATE FLUSH, because CLAIM_EPOCH_MINUTES
244
+ * equals FLUSH_AFTER_MINUTES. A bucket only becomes due once its OLDEST
245
+ * pending item is FLUSH_AFTER_MINUTES old, and a flush stamps every
246
+ * pending row in the bucket - so the next legitimate flush of the same
247
+ * bucket cannot happen until at least FLUSH_AFTER_MINUTES later, which is
248
+ * a strictly later epoch. What the index does block is a SECOND flush
249
+ * inside the same epoch, which is exactly the duplicate we want gone, and
250
+ * that is also where the hard "at most 60 / CLAIM_EPOCH_MINUTES rollups
251
+ * per hour per address" bound comes from.
252
+ */
253
+ const epochMs = CLAIM_EPOCH_MINUTES * MILLISECONDS_PER_MINUTE;
254
+ const epochStart = new Date(Math.floor(now.getTime() / epochMs) * epochMs);
255
+ const batch = new UserNotificationEmailRollupBatch();
256
+ batch.projectId = bucket.projectId;
257
+ batch.userId = bucket.userId;
258
+ batch.toEmail = bucket.toEmail;
259
+ batch.claimEpochStartsAt = epochStart;
260
+ batch.claimedAt = now;
261
+ batch.status = RollupBatchStatus.Claimed;
262
+ let created;
263
+ try {
264
+ created = await UserNotificationEmailRollupBatchService.create({
265
+ data: batch,
266
+ props: {
267
+ isRoot: true,
268
+ },
269
+ });
270
+ }
271
+ catch (err) {
272
+ if (PostgresErrorTranslator.isUniqueViolation(err)) {
273
+ /*
274
+ * Somebody else owns this bucket's epoch. Silently, and without
275
+ * touching a single item row: the winner is about to stamp them.
276
+ */
277
+ return RollupFlushOutcome.Collision;
278
+ }
279
+ throw err;
280
+ }
281
+ const batchId = created.id;
282
+ if (!batchId) {
283
+ throw new Error(`${ROLLUP_JOB_NAME}: the rollup batch claim returned no id.`);
284
+ }
285
+ /*
286
+ * EVERYTHING PAST THE CLAIM IS INSIDE THIS TRY, and that is the point of
287
+ * splitting the method here.
288
+ *
289
+ * Once the stamp lands, up to MAX_ITEMS_PER_ROLLUP notifications exist
290
+ * ONLY as an obligation to send this one email. If anything between the
291
+ * stamp and the send throws - the recipient re-validation, the project
292
+ * lookup, the dashboard URL, the renderer, a bug added here later - and
293
+ * the exception is merely logged by the sweep's per-bucket handler, those
294
+ * notifications are gone: stamped so nothing will ever pick them up again,
295
+ * with a batch row still saying Claimed and no trace of what happened.
296
+ * Recording Failed with the reason is the difference between a bounded,
297
+ * diagnosable loss and a silent one.
298
+ */
299
+ try {
300
+ return await EmailRollupFlushRunner.sendClaimedBatch(bucket, batchId, now);
301
+ }
302
+ catch (err) {
303
+ logger.error(err, {
304
+ projectId: bucket.projectId.toString(),
305
+ userId: bucket.userId.toString(),
306
+ });
307
+ try {
308
+ /*
309
+ * Counted rather than assumed zero. If the throw happened after the
310
+ * stamp, rows are already carrying this batch's id and the whole point
311
+ * of recording Failed is to say how many notifications went with it; a
312
+ * hard-coded 0 would make the ledger claim a loss of nothing. One
313
+ * extra query, only on the failure path.
314
+ */
315
+ const stampedCount = await UserNotificationEmailRollupItemService.countBy({
316
+ query: {
317
+ rollupBatchId: batchId,
318
+ },
319
+ props: {
320
+ isRoot: true,
321
+ },
322
+ });
323
+ await EmailRollupFlushRunner.finish({
324
+ batchId: batchId,
325
+ status: RollupBatchStatus.Failed,
326
+ itemCount: stampedCount.toNumber(),
327
+ now: now,
328
+ message: EmailRollupFlushRunner.describeError(err),
329
+ });
330
+ }
331
+ catch (finishErr) {
332
+ // Nothing further to try; the batch row keeps its Claimed status.
333
+ logger.error(finishErr);
334
+ }
335
+ return RollupFlushOutcome.Failed;
336
+ }
337
+ }
338
+ /*
339
+ * The half of a flush that runs after the epoch has been claimed: stamp the
340
+ * oldest pending rows into this batch, render them, and send. Separated so
341
+ * every failure in it is caught and recorded against the batch rather than
342
+ * escaping to the sweep loop, where it would leave stamped-but-unsent rows.
343
+ */
344
+ static async sendClaimedBatch(bucket, batchId, now) {
345
+ var _a;
346
+ /*
347
+ * STAMP BEFORE SEND, and bounded.
348
+ *
349
+ * The alternative - send first, stamp after - means a permanently broken
350
+ * SMTP server produces a rollup that grows every epoch and is re-sent
351
+ * every epoch, forever. That is precisely the storm this feature exists to
352
+ * stop, so it is not an acceptable failure mode here even though it is the
353
+ * more forgiving one elsewhere. The price is that a hard send failure
354
+ * loses that batch's notifications; that loss is bounded at
355
+ * MAX_ITEMS_PER_ROLLUP, is written down on the batch row with its reason,
356
+ * and the underlying resources are all still in the dashboard.
357
+ *
358
+ * The query deliberately DROPS the cutoff and takes every pending row for
359
+ * the bucket, including ones written seconds ago. Coalescing more is
360
+ * strictly better for the recipient, and it can only ever make an item's
361
+ * latency shorter than the schedule promised, never longer.
362
+ *
363
+ * THE OLDEST ROWS ARE SELECTED EXPLICITLY, AND THAT TAKES TWO STEPS.
364
+ * updateBy resolves the rows it will write with an internal _findBy that
365
+ * takes no sort from the caller (UpdateBy has no sort field) and therefore
366
+ * gets DatabaseService's default of createdAt DESCENDING. A bare
367
+ * `updateBy(..., limit: 500)` on an over-full bucket would consequently
368
+ * stamp the NEWEST five hundred and leave the oldest pending - a LIFO
369
+ * queue whose tail is never served, and whose tail is then hard-deleted
370
+ * unsent at ROLLUP_ITEM_RETENTION_DAYS. Selecting the ids oldest-first and
371
+ * updating exactly those makes the drain FIFO, which is the only ordering
372
+ * a notification queue may have.
373
+ */
374
+ const oldestPending = await UserNotificationEmailRollupItemService.findBy({
375
+ query: {
376
+ projectId: bucket.projectId,
377
+ userId: bucket.userId,
378
+ toEmail: bucket.toEmail,
379
+ sentAt: QueryHelper.isNull(),
380
+ },
381
+ select: {
382
+ _id: true,
383
+ },
384
+ sort: {
385
+ createdAt: SortOrder.Ascending,
386
+ },
387
+ limit: MAX_ITEMS_PER_ROLLUP,
388
+ skip: 0,
389
+ props: {
390
+ isRoot: true,
391
+ },
392
+ });
393
+ const pendingIds = oldestPending
394
+ .map((item) => {
395
+ return item.id;
396
+ })
397
+ .filter((id) => {
398
+ return id !== null;
399
+ });
400
+ if (pendingIds.length === 0) {
401
+ await EmailRollupFlushRunner.finish({
402
+ batchId: batchId,
403
+ status: RollupBatchStatus.Empty,
404
+ itemCount: 0,
405
+ now: now,
406
+ });
407
+ return RollupFlushOutcome.Empty;
408
+ }
409
+ const stamped = await UserNotificationEmailRollupItemService.updateBy({
410
+ query: {
411
+ _id: QueryHelper.any(pendingIds.map((id) => {
412
+ return id.toString();
413
+ })),
414
+ /*
415
+ * Belt and braces with the id list: a row that somebody else stamped
416
+ * between the select above and this write must not be re-stamped
417
+ * into this batch, or it would appear in two rollups.
418
+ */
419
+ sentAt: QueryHelper.isNull(),
420
+ },
421
+ data: {
422
+ sentAt: now,
423
+ rollupBatchId: batchId,
424
+ },
425
+ limit: MAX_ITEMS_PER_ROLLUP,
426
+ skip: 0,
427
+ props: {
428
+ isRoot: true,
429
+ ignoreHooks: true,
430
+ },
431
+ });
432
+ if (stamped === 0) {
433
+ await EmailRollupFlushRunner.finish({
434
+ batchId: batchId,
435
+ status: RollupBatchStatus.Empty,
436
+ itemCount: 0,
437
+ now: now,
438
+ });
439
+ return RollupFlushOutcome.Empty;
440
+ }
441
+ /*
442
+ * READ BACK BY BATCH, never by "still pending for this bucket": this is
443
+ * what guarantees the email describes exactly the rows this attempt owns.
444
+ */
445
+ const items = await UserNotificationEmailRollupItemService.findBy({
446
+ query: {
447
+ rollupBatchId: batchId,
448
+ },
449
+ select: {
450
+ eventType: true,
451
+ rollupCategory: true,
452
+ subject: true,
453
+ viewLink: true,
454
+ createdAt: true,
455
+ },
456
+ sort: {
457
+ createdAt: SortOrder.Ascending,
458
+ },
459
+ limit: MAX_ITEMS_PER_ROLLUP,
460
+ skip: 0,
461
+ props: {
462
+ isRoot: true,
463
+ },
464
+ });
465
+ if (items.length === 0) {
466
+ await EmailRollupFlushRunner.finish({
467
+ batchId: batchId,
468
+ status: RollupBatchStatus.Empty,
469
+ itemCount: 0,
470
+ now: now,
471
+ });
472
+ return RollupFlushOutcome.Empty;
473
+ }
474
+ /*
475
+ * RE-VALIDATE THE RECIPIENT. The address was snapshotted minutes ago when
476
+ * the first item was queued, and the individual sends this rollup replaces
477
+ * would each have re-read the verified set at send time. An address that
478
+ * has since been unverified or removed must not be handed a list of this
479
+ * project's incident subjects.
480
+ */
481
+ const verified = await UserEmailService.findBy({
482
+ query: {
483
+ userId: bucket.userId,
484
+ projectId: bucket.projectId,
485
+ isVerified: true,
486
+ },
487
+ select: {
488
+ email: true,
489
+ },
490
+ limit: LIMIT_PER_PROJECT,
491
+ skip: 0,
492
+ props: {
493
+ isRoot: true,
494
+ },
495
+ });
496
+ const stillVerified = verified.some((userEmail) => {
497
+ var _a;
498
+ return ((_a = userEmail.email) === null || _a === void 0 ? void 0 : _a.toString()) === bucket.toEmail.toString();
499
+ });
500
+ if (!stillVerified) {
501
+ await EmailRollupFlushRunner.finish({
502
+ batchId: batchId,
503
+ status: RollupBatchStatus.Skipped,
504
+ itemCount: items.length,
505
+ now: now,
506
+ message: "address is no longer a verified email for this user",
507
+ });
508
+ return RollupFlushOutcome.Skipped;
509
+ }
510
+ /*
511
+ * The project name is READ, not snapshotted at enqueue: one query per
512
+ * rollup email, always showing the project's current name, and it doubles
513
+ * as the "has this project been deleted while items were queued?" check.
514
+ */
515
+ const project = await ProjectService.findOneById({
516
+ id: bucket.projectId,
517
+ select: {
518
+ name: true,
519
+ },
520
+ props: {
521
+ isRoot: true,
522
+ },
523
+ });
524
+ if (!project) {
525
+ await EmailRollupFlushRunner.finish({
526
+ batchId: batchId,
527
+ status: RollupBatchStatus.Skipped,
528
+ itemCount: items.length,
529
+ now: now,
530
+ message: "project not found",
531
+ });
532
+ return RollupFlushOutcome.Skipped;
533
+ }
534
+ const dashboardUrl = await DatabaseConfig.getDashboardUrl();
535
+ /*
536
+ * addRoute mutates the URL it is called on, so each link starts from a
537
+ * fresh URL parsed out of the dashboard URL's string rather than from the
538
+ * shared instance.
539
+ */
540
+ const projectHomeLink = URL.fromString(dashboardUrl.toString())
541
+ .addRoute(`/${bucket.projectId.toString()}/home`)
542
+ .toString();
543
+ const preferencesLink = URL.fromString(dashboardUrl.toString())
544
+ .addRoute(`/${bucket.projectId.toString()}/user-settings/notification-settings`)
545
+ .toString();
546
+ const built = buildRollupEmail({
547
+ projectName: (_a = project.name) !== null && _a !== void 0 ? _a : "",
548
+ projectHomeLink: projectHomeLink,
549
+ preferencesLink: preferencesLink,
550
+ items: items,
551
+ });
552
+ try {
553
+ /*
554
+ * AWAITED, unlike the fire-and-forget individual sends: a rollup that
555
+ * failed has to be recorded as Failed, and the only way to know is to
556
+ * wait for it.
557
+ *
558
+ * The options carry projectId and userId and NOTHING else. projectId is
559
+ * required for MailService to write an EmailLog row at all, so omitting
560
+ * it would make rollups invisible in Notification Logs; and a rollup
561
+ * spans many resources, so there is no single incident, alert or monitor
562
+ * it could honestly be correlated with.
563
+ */
564
+ await EmailRollupFlushRunner.withSendTimeout(MailService.sendMail({
565
+ toEmail: bucket.toEmail,
566
+ subject: built.subject,
567
+ templateType: EmailTemplateType.NotificationRollup,
568
+ vars: built.vars,
569
+ }, {
570
+ projectId: bucket.projectId,
571
+ userId: bucket.userId,
572
+ }));
573
+ }
574
+ catch (err) {
575
+ logger.error(err, {
576
+ projectId: bucket.projectId.toString(),
577
+ userId: bucket.userId.toString(),
578
+ });
579
+ await EmailRollupFlushRunner.finish({
580
+ batchId: batchId,
581
+ status: RollupBatchStatus.Failed,
582
+ itemCount: items.length,
583
+ now: now,
584
+ message: EmailRollupFlushRunner.describeError(err),
585
+ });
586
+ return RollupFlushOutcome.Failed;
587
+ }
588
+ await EmailRollupFlushRunner.finish({
589
+ batchId: batchId,
590
+ status: RollupBatchStatus.Sent,
591
+ itemCount: items.length,
592
+ now: now,
593
+ });
594
+ return RollupFlushOutcome.Sent;
595
+ }
596
+ /**
597
+ * Close out a claim row. sentAt is stamped only for a real send, so a batch
598
+ * row with a NULL sentAt and a non-Claimed status is always a rollup that
599
+ * did not go out, and statusMessage says why.
600
+ */
601
+ static async finish(data) {
602
+ var _a;
603
+ const update = {
604
+ status: data.status,
605
+ itemCount: data.itemCount,
606
+ };
607
+ if (data.status === RollupBatchStatus.Sent) {
608
+ update.sentAt = data.now;
609
+ }
610
+ if (data.message !== undefined) {
611
+ /*
612
+ * Guarded assignment: exactOptionalPropertyTypes means an optional
613
+ * property will not take an explicit undefined.
614
+ */
615
+ update.statusMessage =
616
+ (_a = Text.truncate(data.message, STATUS_MESSAGE_MAX_LENGTH)) !== null && _a !== void 0 ? _a : "";
617
+ }
618
+ await UserNotificationEmailRollupBatchService.updateOneById({
619
+ id: data.batchId,
620
+ data: update,
621
+ props: {
622
+ isRoot: true,
623
+ },
624
+ });
625
+ }
626
+ /*
627
+ * A thrown value is `unknown`, and the one thing the batch row must never do
628
+ * is fail to record a failure - so this never touches anything that could
629
+ * throw on a hostile value.
630
+ */
631
+ static describeError(err) {
632
+ if (err instanceof Error && err.message) {
633
+ return err.message;
634
+ }
635
+ if (typeof err === "string") {
636
+ return err;
637
+ }
638
+ return "unknown error";
639
+ }
640
+ /*
641
+ * Rejects if the send has not settled within ROLLUP_SEND_TIMEOUT_MS. See
642
+ * that constant for why a hung send is worse here than anywhere else.
643
+ *
644
+ * The underlying request is NOT cancelled - nothing in the stack can cancel
645
+ * it - so the mail may still go out afterwards. That is the right trade: the
646
+ * cost of being wrong is one duplicate rollup for one recipient, and the
647
+ * cost of not doing it is every rollup on the install stopping forever. The
648
+ * batch is recorded Failed either way, so the duplicate is explicable.
649
+ *
650
+ * The timer is always cleared, including on the happy path, so a pending
651
+ * setTimeout can never hold the worker process open at shutdown.
652
+ */
653
+ static async withSendTimeout(send) {
654
+ let timer = undefined;
655
+ const timeout = new Promise((_resolve, reject) => {
656
+ timer = setTimeout(() => {
657
+ reject(new Error(`${ROLLUP_JOB_NAME}: the rollup send did not complete within ${ROLLUP_SEND_TIMEOUT_MS}ms.`));
658
+ }, ROLLUP_SEND_TIMEOUT_MS);
659
+ });
660
+ try {
661
+ await Promise.race([send, timeout]);
662
+ }
663
+ finally {
664
+ if (timer !== undefined) {
665
+ clearTimeout(timer);
666
+ }
667
+ /*
668
+ * Promise.race leaves the loser unhandled. When the timeout wins, the
669
+ * send is still in flight and will eventually settle; without this its
670
+ * rejection would surface as an unhandled rejection and, depending on
671
+ * the runtime's setting, take the worker down.
672
+ */
673
+ send.catch((err) => {
674
+ logger.error(err);
675
+ });
676
+ }
677
+ }
678
+ }
679
+ __decorate([
680
+ CaptureSpan(),
681
+ __metadata("design:type", Function),
682
+ __metadata("design:paramtypes", [Object]),
683
+ __metadata("design:returntype", Promise)
684
+ ], EmailRollupFlushRunner, "runSweepUnderLock", null);
685
+ __decorate([
686
+ CaptureSpan(),
687
+ __metadata("design:type", Function),
688
+ __metadata("design:paramtypes", [Object]),
689
+ __metadata("design:returntype", Promise)
690
+ ], EmailRollupFlushRunner, "runSweep", null);
691
+ //# sourceMappingURL=EmailRollupFlushRunner.js.map