@oneuptime/common 12.0.31 → 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 (747) hide show
  1. package/Models/AnalyticsModels/Span.ts +14 -0
  2. package/Models/DatabaseModels/AlertState.ts +0 -2
  3. package/Models/DatabaseModels/Domain.ts +1 -1
  4. package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
  5. package/Models/DatabaseModels/Incident.ts +1 -1
  6. package/Models/DatabaseModels/IncidentTemplate.ts +1 -1
  7. package/Models/DatabaseModels/Index.ts +12 -0
  8. package/Models/DatabaseModels/MetricType.ts +0 -2
  9. package/Models/DatabaseModels/Monitor.ts +76 -0
  10. package/Models/DatabaseModels/MonitorStatusTimeline.ts +0 -2
  11. package/Models/DatabaseModels/MonitorTest.ts +0 -2
  12. package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
  13. package/Models/DatabaseModels/NetworkDevice.ts +297 -3
  14. package/Models/DatabaseModels/NetworkDeviceOidTemplate.ts +3 -1
  15. package/Models/DatabaseModels/NetworkDeviceRole.ts +648 -0
  16. package/Models/DatabaseModels/NetworkSite.ts +201 -2
  17. package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
  18. package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
  19. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -1
  20. package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -1
  21. package/Models/DatabaseModels/StatusPageAnnouncement.ts +0 -2
  22. package/Models/DatabaseModels/StatusPageAnnouncementTemplate.ts +0 -2
  23. package/Models/DatabaseModels/StatusPagePrivateUser.ts +0 -2
  24. package/Models/DatabaseModels/StatusPageResource.ts +0 -2
  25. package/Models/DatabaseModels/StatusPageSubscriber.ts +0 -2
  26. package/Models/DatabaseModels/TelemetryException.ts +119 -0
  27. package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
  28. package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
  29. package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
  30. package/Server/API/EnterpriseLicenseAPI.ts +391 -64
  31. package/Server/API/LlmProviderAPI.ts +137 -22
  32. package/Server/EnvironmentConfig.ts +14 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.ts +72 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  41. package/Server/Infrastructure/QueueWorker.ts +38 -8
  42. package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
  43. package/Server/Middleware/ProjectAuthorization.ts +11 -0
  44. package/Server/Middleware/SCIMAuthorization.ts +12 -0
  45. package/Server/Middleware/TelemetryIngest.ts +11 -0
  46. package/Server/Services/AIBillingService.ts +101 -27
  47. package/Server/Services/DatabaseService.ts +39 -9
  48. package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
  49. package/Server/Services/EnterpriseLicenseService.ts +55 -0
  50. package/Server/Services/Index.ts +12 -0
  51. package/Server/Services/MonitorService.ts +143 -21
  52. package/Server/Services/MonitorStatusTimelineService.ts +150 -8
  53. package/Server/Services/MonitorTemplateService.ts +217 -1
  54. package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
  55. package/Server/Services/NetworkAlertPolicyService.ts +944 -0
  56. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +9 -10
  57. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
  58. package/Server/Services/NetworkDeviceRoleService.ts +90 -0
  59. package/Server/Services/NetworkDeviceService.ts +1032 -73
  60. package/Server/Services/NetworkSiteService.ts +1502 -129
  61. package/Server/Services/NetworkSiteTypeService.ts +1216 -0
  62. package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
  63. package/Server/Services/NotificationService.ts +118 -28
  64. package/Server/Services/ProjectService.ts +186 -44
  65. package/Server/Services/StatusPagePrivateUserService.ts +103 -3
  66. package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
  67. package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
  68. package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
  69. package/Server/Services/UserNotificationSettingService.ts +62 -31
  70. package/Server/Services/UserService.ts +95 -0
  71. package/Server/Types/Database/QueryHelper.ts +2 -2
  72. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
  73. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
  74. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
  75. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
  76. package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
  77. package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
  78. package/Server/Utils/DataSource/HttpFetch.ts +9 -2
  79. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
  80. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
  81. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
  82. package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
  83. package/Server/Utils/LLM/LLMService.ts +78 -0
  84. package/Server/Utils/LogRedaction.ts +8 -0
  85. package/Server/Utils/Logger.ts +79 -1
  86. package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
  87. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
  88. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
  89. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  90. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
  91. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
  92. package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
  93. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -0
  94. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
  95. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
  96. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
  97. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
  98. package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
  99. package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
  100. package/Server/Utils/OutboundUserAgent.ts +152 -0
  101. package/Server/Utils/StartServer.ts +51 -19
  102. package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
  103. package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
  104. package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
  105. package/Server/Utils/Telemetry.ts +198 -51
  106. package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
  107. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +158 -27
  108. package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
  109. package/Tests/App/Dashboard/DashboardChartWidgetZoom.test.tsx +35 -8
  110. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +107 -3
  111. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
  112. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
  113. package/Tests/App/Dashboard/DashboardWideChartZoom.test.tsx +401 -0
  114. package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
  115. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -9
  116. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
  117. package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
  118. package/Tests/App/Dashboard/MonitorTemplateColumnAndFacet.test.tsx +318 -0
  119. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
  120. package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +357 -0
  121. package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
  122. package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
  123. package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
  124. package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
  125. package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
  126. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +626 -0
  127. package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
  128. package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
  129. package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
  130. package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
  131. package/Tests/App/Dashboard/SideMenuHarness.tsx +11 -3
  132. package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
  133. package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
  134. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
  135. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
  136. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
  137. package/Tests/Models/DatabaseModels/ModelRegistryInvariants.test.ts +115 -41
  138. package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
  139. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
  140. package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
  141. package/Tests/Server/Infrastructure/Postgres/NetworkDeviceRoleTableMigration.test.ts +476 -0
  142. package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
  143. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
  144. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
  145. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
  146. package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
  147. package/Tests/Server/Services/DatabaseServiceGenerateSlug.test.ts +215 -0
  148. package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
  149. package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
  150. package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
  151. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
  152. package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
  153. package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
  154. package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
  155. package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
  156. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +47 -4
  157. package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
  158. package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
  159. package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
  160. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
  161. package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
  162. package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
  163. package/Tests/Server/Services/NetworkDeviceRoleModel.test.ts +672 -0
  164. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +1 -1
  165. package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
  166. package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
  167. package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
  168. package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
  169. package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
  170. package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
  171. package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
  172. package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +67 -4
  173. package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
  174. package/Tests/Server/Services/ScheduledMaintenanceSubscriberEndTime.test.ts +369 -0
  175. package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
  176. package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
  177. package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
  178. package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
  179. package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
  180. package/Tests/Server/Services/UserNotificationSettingMonitorDefaults.test.ts +248 -0
  181. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +856 -0
  182. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +145 -3
  183. package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
  184. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
  185. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
  186. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
  187. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
  188. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
  189. package/Tests/Server/Utils/BasicCron.test.ts +283 -0
  190. package/Tests/Server/Utils/Captcha.test.ts +422 -0
  191. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
  192. package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
  193. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
  194. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
  195. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
  196. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
  197. package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
  198. package/Tests/Server/Utils/IncomingCallPhoneNumber.test.ts +174 -0
  199. package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
  200. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
  201. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
  202. package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
  203. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
  204. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
  205. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
  206. package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
  207. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
  208. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
  209. package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
  210. package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
  211. package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
  212. package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
  213. package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
  214. package/Tests/Server/Utils/Telemetry.test.ts +456 -66
  215. package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
  216. package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
  217. package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
  218. package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
  219. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
  220. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
  221. package/Tests/Types/NetworkDevice/DefaultNetworkDeviceRole.test.ts +417 -0
  222. package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
  223. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
  224. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
  225. package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
  226. package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
  227. package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
  228. package/Tests/UI/Components/Charts/ChartClickDoubleClickDisambiguation.test.tsx +221 -0
  229. package/Tests/UI/Components/Charts/ChartDoubleClickReset.test.tsx +220 -0
  230. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +751 -0
  231. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +475 -43
  232. package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +89 -0
  233. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
  234. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +103 -8
  235. package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
  236. package/Tests/UI/Components/SideMenuItem.test.tsx +256 -4
  237. package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
  238. package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
  239. package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
  240. package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
  241. package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
  242. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +30 -0
  243. package/Tests/UI/Utils/UseDashboardTimeRangeZoom.test.tsx +187 -0
  244. package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +302 -0
  245. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +242 -0
  246. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
  247. package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
  248. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
  249. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
  250. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  251. package/Tests/Utils/Monitor/NetworkDeviceRoleCatalog.test.ts +981 -0
  252. package/Tests/Utils/Monitor/NetworkTopologyRoleCatalog.test.ts +865 -0
  253. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
  254. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
  255. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
  256. package/Tests/Utils/NetworkDevice/DeviceRoleKeyUtil.test.ts +538 -0
  257. package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
  258. package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
  259. package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
  260. package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
  261. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
  262. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
  263. package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
  264. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
  265. package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
  266. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
  267. package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
  268. package/Tests/Utils/Slo/SloEvaluation.test.ts +171 -0
  269. package/Tests/Utils/Slug.test.ts +61 -1
  270. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
  271. package/Tests/jest.setup.ts +19 -0
  272. package/Types/AI/ExceptionAIClassification.ts +10 -24
  273. package/Types/Email/EmailTemplateType.ts +2 -0
  274. package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
  275. package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
  276. package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
  277. package/Types/Exception/ApiException.ts +10 -0
  278. package/Types/Exception/BadDataException.ts +11 -0
  279. package/Types/Exception/BadRequestException.ts +11 -0
  280. package/Types/Exception/Exception.ts +65 -0
  281. package/Types/Exception/ForbiddenException.ts +10 -0
  282. package/Types/Exception/NotAuthenticatedException.ts +10 -0
  283. package/Types/Exception/NotAuthorizedException.ts +10 -0
  284. package/Types/Exception/NotFoundException.ts +11 -0
  285. package/Types/Exception/PayloadTooLargeException.ts +11 -0
  286. package/Types/Exception/PaymentRequiredException.ts +10 -0
  287. package/Types/Exception/ServiceUnavailableException.ts +10 -0
  288. package/Types/Exception/SsoAuthorizationException.ts +10 -0
  289. package/Types/Exception/TenantNotFoundException.ts +11 -0
  290. package/Types/Exception/TimeoutException.ts +10 -0
  291. package/Types/Exception/TooManyRequestsException.ts +10 -0
  292. package/Types/Exception/UnableToReachServer.ts +10 -0
  293. package/Types/Exception/WebsiteRequestException.ts +10 -0
  294. package/Types/Monitor/CriteriaFilter.ts +60 -2
  295. package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
  296. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
  297. package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
  298. package/Types/Monitor/MonitorMetricType.ts +71 -0
  299. package/Types/Monitor/MonitorStep.ts +76 -0
  300. package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
  301. package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
  302. package/Types/Monitor/MonitorType.ts +47 -1
  303. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
  304. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +61 -0
  305. package/Types/Monitor/SqlConnectionConfig.ts +31 -0
  306. package/Types/NetworkDevice/DefaultNetworkDeviceRole.ts +145 -0
  307. package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
  308. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
  309. package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
  310. package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
  311. package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
  312. package/Types/Permission.ts +135 -0
  313. package/Types/Probe/ProbeMonitorResponse.ts +16 -0
  314. package/Types/Telemetry/ErrorClass.ts +274 -0
  315. package/Types/Telemetry/UnitOfWork.ts +59 -0
  316. package/UI/Components/Charts/Area/AreaChart.tsx +7 -0
  317. package/UI/Components/Charts/Bar/BarChart.tsx +6 -0
  318. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +9 -1
  319. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +97 -35
  320. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +14 -0
  321. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +97 -35
  322. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +13 -0
  323. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  324. package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
  325. package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
  326. package/UI/Components/Modal/Modal.tsx +2 -8
  327. package/UI/Components/ModelTable/BaseModelTable.tsx +50 -15
  328. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  329. package/UI/Components/Navbar/NavBar.tsx +62 -13
  330. package/UI/Components/Navbar/NavBarMenuModal.tsx +7 -2
  331. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
  332. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
  333. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +2 -0
  334. package/UI/Components/SideMenu/SideMenu.tsx +135 -7
  335. package/UI/Components/SideMenu/SideMenuItem.tsx +80 -85
  336. package/UI/Components/SideMenu/SideMenuSection.tsx +69 -25
  337. package/UI/Components/SideOver/SideOver.tsx +21 -20
  338. package/UI/Utils/PageScrollLock.ts +79 -3
  339. package/UI/Utils/PermissionGate.ts +61 -0
  340. package/UI/Utils/SensitiveUrlToken.ts +112 -0
  341. package/UI/Utils/TestLLMProvider.ts +11 -0
  342. package/UI/Utils/UseDashboardTimeRangeZoom.ts +77 -0
  343. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +118 -0
  344. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
  345. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
  346. package/Utils/Monitor/MonitorMetricType.ts +153 -1
  347. package/Utils/Monitor/NetworkDeviceRoleCatalog.ts +232 -0
  348. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +2 -1
  349. package/Utils/Monitor/NetworkTopologyUtil.ts +139 -36
  350. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
  351. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
  352. package/Utils/NetworkDevice/DeviceRoleKeyUtil.ts +137 -0
  353. package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
  354. package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
  355. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
  356. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
  357. package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
  358. package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
  359. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
  360. package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
  361. package/Utils/Rules/RulePatternMatchUtil.ts +1 -1
  362. package/Utils/Slug.ts +34 -1
  363. package/build/dist/Models/AnalyticsModels/Span.js +14 -0
  364. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/AlertState.js +0 -2
  366. package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -1
  367. package/build/dist/Models/DatabaseModels/Domain.js +1 -1
  368. package/build/dist/Models/DatabaseModels/Domain.js.map +1 -1
  369. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
  370. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  371. package/build/dist/Models/DatabaseModels/Incident.js +1 -1
  372. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  373. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +1 -1
  374. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  375. package/build/dist/Models/DatabaseModels/Index.js +12 -0
  376. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  377. package/build/dist/Models/DatabaseModels/MetricType.js +0 -2
  378. package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
  379. package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
  380. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  381. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +0 -2
  382. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  383. package/build/dist/Models/DatabaseModels/MonitorTest.js +0 -2
  384. package/build/dist/Models/DatabaseModels/MonitorTest.js.map +1 -1
  385. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
  386. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
  387. package/build/dist/Models/DatabaseModels/NetworkDevice.js +304 -4
  388. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  389. package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js +3 -1
  390. package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js.map +1 -1
  391. package/build/dist/Models/DatabaseModels/NetworkDeviceRole.js +677 -0
  392. package/build/dist/Models/DatabaseModels/NetworkDeviceRole.js.map +1 -0
  393. package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
  394. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  395. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
  396. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
  397. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
  398. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
  399. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -1
  400. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  401. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -1
  402. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
  403. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +0 -2
  404. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  405. package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js +0 -2
  406. package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js.map +1 -1
  407. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +0 -2
  408. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  409. package/build/dist/Models/DatabaseModels/StatusPageResource.js +0 -2
  410. package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
  411. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +0 -2
  412. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
  413. package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
  414. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  415. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
  416. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
  417. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
  418. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
  419. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
  420. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
  421. package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
  422. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  423. package/build/dist/Server/API/LlmProviderAPI.js +108 -13
  424. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  425. package/build/dist/Server/EnvironmentConfig.js +12 -0
  426. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  427. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
  428. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
  429. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.js +39 -0
  430. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.js.map +1 -0
  431. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
  432. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
  433. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
  434. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
  435. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
  436. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
  437. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
  438. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
  439. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
  440. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
  441. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  442. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  443. package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
  444. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  445. package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
  446. package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
  447. package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
  448. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  449. package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
  450. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
  451. package/build/dist/Server/Middleware/TelemetryIngest.js +11 -0
  452. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  453. package/build/dist/Server/Services/AIBillingService.js +70 -16
  454. package/build/dist/Server/Services/AIBillingService.js.map +1 -1
  455. package/build/dist/Server/Services/DatabaseService.js +31 -5
  456. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  457. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
  458. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
  459. package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
  460. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  461. package/build/dist/Server/Services/Index.js +12 -0
  462. package/build/dist/Server/Services/Index.js.map +1 -1
  463. package/build/dist/Server/Services/MonitorService.js +119 -21
  464. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  465. package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
  466. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  467. package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
  468. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  469. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
  470. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
  471. package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
  472. package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
  473. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +10 -9
  474. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  475. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
  476. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  477. package/build/dist/Server/Services/NetworkDeviceRoleService.js +70 -0
  478. package/build/dist/Server/Services/NetworkDeviceRoleService.js.map +1 -0
  479. package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
  480. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  481. package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
  482. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  483. package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
  484. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
  485. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
  486. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
  487. package/build/dist/Server/Services/NotificationService.js +80 -17
  488. package/build/dist/Server/Services/NotificationService.js.map +1 -1
  489. package/build/dist/Server/Services/ProjectService.js +131 -30
  490. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  491. package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
  492. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  493. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
  494. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
  495. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
  496. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
  497. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
  498. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
  499. package/build/dist/Server/Services/UserNotificationSettingService.js +46 -21
  500. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  501. package/build/dist/Server/Services/UserService.js +90 -0
  502. package/build/dist/Server/Services/UserService.js.map +1 -1
  503. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  504. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  505. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
  506. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  507. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
  508. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  509. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
  510. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  511. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
  512. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
  513. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
  514. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  515. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
  516. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
  517. package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
  518. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  519. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +91 -0
  520. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
  521. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -0
  522. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
  523. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
  524. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
  525. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
  526. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
  527. package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
  528. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  529. package/build/dist/Server/Utils/LogRedaction.js +8 -0
  530. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  531. package/build/dist/Server/Utils/Logger.js +63 -1
  532. package/build/dist/Server/Utils/Logger.js.map +1 -1
  533. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
  534. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
  535. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  536. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  537. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
  538. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  539. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  540. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  541. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +37 -0
  542. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  543. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
  544. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  545. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  546. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  547. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -0
  548. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  549. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
  550. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  551. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
  552. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  553. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
  554. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  555. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
  556. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  557. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
  558. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
  559. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
  560. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
  561. package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
  562. package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
  563. package/build/dist/Server/Utils/StartServer.js +38 -14
  564. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  565. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
  566. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  567. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
  568. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
  569. package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
  570. package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
  571. package/build/dist/Server/Utils/Telemetry.js +162 -46
  572. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  573. package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
  574. package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
  575. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  576. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  577. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
  578. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
  579. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
  580. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
  581. package/build/dist/Types/Exception/ApiException.js +9 -0
  582. package/build/dist/Types/Exception/ApiException.js.map +1 -1
  583. package/build/dist/Types/Exception/BadDataException.js +10 -0
  584. package/build/dist/Types/Exception/BadDataException.js.map +1 -1
  585. package/build/dist/Types/Exception/BadRequestException.js +10 -0
  586. package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
  587. package/build/dist/Types/Exception/Exception.js +56 -0
  588. package/build/dist/Types/Exception/Exception.js.map +1 -1
  589. package/build/dist/Types/Exception/ForbiddenException.js +9 -0
  590. package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
  591. package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
  592. package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
  593. package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
  594. package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
  595. package/build/dist/Types/Exception/NotFoundException.js +10 -0
  596. package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
  597. package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
  598. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
  599. package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
  600. package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
  601. package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
  602. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
  603. package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
  604. package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
  605. package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
  606. package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
  607. package/build/dist/Types/Exception/TimeoutException.js +9 -0
  608. package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
  609. package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
  610. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
  611. package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
  612. package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
  613. package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
  614. package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
  615. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
  616. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  617. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
  618. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
  619. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
  620. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
  621. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
  622. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  623. package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
  624. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  625. package/build/dist/Types/Monitor/MonitorStep.js +54 -0
  626. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  627. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
  628. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
  629. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  630. package/build/dist/Types/Monitor/MonitorType.js +45 -1
  631. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  632. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
  633. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  634. package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
  635. package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
  636. package/build/dist/Types/NetworkDevice/DefaultNetworkDeviceRole.js +105 -0
  637. package/build/dist/Types/NetworkDevice/DefaultNetworkDeviceRole.js.map +1 -0
  638. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
  639. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
  640. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
  641. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
  642. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
  643. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
  644. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
  645. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
  646. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
  647. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
  648. package/build/dist/Types/Permission.js +120 -0
  649. package/build/dist/Types/Permission.js.map +1 -1
  650. package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
  651. package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
  652. package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
  653. package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
  654. package/build/dist/UI/Components/Charts/Area/AreaChart.js +1 -1
  655. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  656. package/build/dist/UI/Components/Charts/Bar/BarChart.js +1 -1
  657. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  658. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +6 -1
  659. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  660. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +79 -31
  661. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  662. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +7 -1
  663. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  664. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +79 -31
  665. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  666. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +14 -0
  667. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -0
  668. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  669. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  670. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
  671. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  672. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
  673. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  674. package/build/dist/UI/Components/Modal/Modal.js +2 -7
  675. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  676. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +39 -13
  677. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  678. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
  679. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  680. package/build/dist/UI/Components/Navbar/NavBar.js +44 -9
  681. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  682. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  683. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  684. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
  685. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  686. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
  687. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  688. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +1 -1
  689. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  690. package/build/dist/UI/Components/SideMenu/SideMenu.js +76 -11
  691. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  692. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +50 -54
  693. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  694. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +32 -9
  695. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  696. package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
  697. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  698. package/build/dist/UI/Utils/PageScrollLock.js +31 -3
  699. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
  700. package/build/dist/UI/Utils/PermissionGate.js +42 -1
  701. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  702. package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
  703. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
  704. package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
  705. package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
  706. package/build/dist/UI/Utils/UseDashboardTimeRangeZoom.js +42 -0
  707. package/build/dist/UI/Utils/UseDashboardTimeRangeZoom.js.map +1 -0
  708. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +74 -0
  709. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -0
  710. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
  711. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
  712. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
  713. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  714. package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
  715. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  716. package/build/dist/Utils/Monitor/NetworkDeviceRoleCatalog.js +126 -0
  717. package/build/dist/Utils/Monitor/NetworkDeviceRoleCatalog.js.map +1 -0
  718. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +2 -1
  719. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -1
  720. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +75 -35
  721. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  722. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
  723. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
  724. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
  725. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  726. package/build/dist/Utils/NetworkDevice/DeviceRoleKeyUtil.js +114 -0
  727. package/build/dist/Utils/NetworkDevice/DeviceRoleKeyUtil.js.map +1 -0
  728. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
  729. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
  730. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
  731. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
  732. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
  733. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  734. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
  735. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  736. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
  737. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
  738. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
  739. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
  740. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
  741. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  742. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
  743. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
  744. package/build/dist/Utils/Rules/RulePatternMatchUtil.js +1 -1
  745. package/build/dist/Utils/Slug.js +31 -1
  746. package/build/dist/Utils/Slug.js.map +1 -1
  747. package/package.json +2 -2
@@ -1,3 +1,5 @@
1
+ import fs from "fs";
2
+ import path from "path";
1
3
  import ProjectService from "../../../Server/Services/ProjectService";
2
4
  import BillingService from "../../../Server/Services/BillingService";
3
5
  import MarketingEventUtil from "../../../Server/Utils/Marketing/MarketingEventUtil";
@@ -8,7 +10,7 @@ import { MarketingEvent } from "../../../Types/Marketing/MarketingEvent";
8
10
  import { resolveEmittedMarketingEvent } from "../Utils/Marketing/EmittedMarketingEvent";
9
11
  import { JSONObject } from "../../../Types/JSON";
10
12
  import ObjectID from "../../../Types/ObjectID";
11
- import { describe, expect, it, afterEach } from "@jest/globals";
13
+ import { describe, expect, it, afterEach, test } from "@jest/globals";
12
14
 
13
15
  /*
14
16
  * A project created directly on a paid plan never passes through changePlan,
@@ -121,9 +123,11 @@ describe("ProjectService project creation - subscription_started", () => {
121
123
  }
122
124
 
123
125
  /*
124
- * The nine default-row seeders run after the conversion is captured and each
125
- * one writes to a different table. None of them are what is under test, so
126
- * they are stubbed out wholesale.
126
+ * The default-row seeders run after the conversion is captured and each one
127
+ * writes to a different table. None of them are what is under test, so they
128
+ * are stubbed out wholesale. This list must name every seeder in
129
+ * ProjectService.onCreateSuccess: one left off reaches a real repository and
130
+ * throws "Database not connected", failing the whole suite.
127
131
  */
128
132
  const DEFAULT_SEEDERS: Array<string> = [
129
133
  "addDefaultIncidentSeverity",
@@ -135,6 +139,7 @@ describe("ProjectService project creation - subscription_started", () => {
135
139
  "addDefaultAlertState",
136
140
  "addDefaultIncidentRoles",
137
141
  "addDefaultNetworkSiteTypes",
142
+ "addDefaultNetworkDeviceRoles",
138
143
  ];
139
144
 
140
145
  function setup(data?: {
@@ -516,4 +521,62 @@ describe("ProjectService project creation - subscription_started", () => {
516
521
  expect(emitOrder).toBeGreaterThan(writeOrder);
517
522
  });
518
523
  });
524
+
525
+ /*
526
+ * The list above is a hand-maintained mirror of the seeders
527
+ * onCreateSuccess runs, and nothing about adding a tenth seeder to the
528
+ * service makes this file fail to compile. When addDefaultNetworkDeviceRoles
529
+ * was added and this list was not updated, the unstubbed seeder reached a
530
+ * real repository and every test in this suite failed with "Database not
531
+ * connected" — on master, not in review.
532
+ *
533
+ * So the mirror is checked against its source. Read as text because
534
+ * onCreateSuccess is protected and the seeder batch is a statement inside
535
+ * it: there is nothing to enumerate at runtime without actually creating a
536
+ * project, which is the thing this suite stubs out.
537
+ */
538
+ describe("the stub list stays in step with the service", () => {
539
+ const PROJECT_SERVICE_SOURCE: string = fs.readFileSync(
540
+ path.join(__dirname, "../../../Server/Services/ProjectService.ts"),
541
+ "utf8",
542
+ );
543
+
544
+ function seedersInCreateHook(): Array<string> {
545
+ const start: number = PROJECT_SERVICE_SOURCE.indexOf(
546
+ "await Promise.all([",
547
+ );
548
+ expect(start).toBeGreaterThan(-1);
549
+
550
+ const block: string = PROJECT_SERVICE_SOURCE.slice(
551
+ start,
552
+ PROJECT_SERVICE_SOURCE.indexOf("]);", start),
553
+ );
554
+
555
+ return Array.from(
556
+ block.matchAll(/this\.(addDefault\w+)\(createdItem\)/g),
557
+ (match: RegExpMatchArray): string => {
558
+ return match[1]!;
559
+ },
560
+ );
561
+ }
562
+
563
+ test("every seeder the create hook runs is stubbed here", () => {
564
+ const inHook: Array<string> = seedersInCreateHook();
565
+
566
+ expect(inHook.length).toBeGreaterThan(0);
567
+ expect(DEFAULT_SEEDERS.slice().sort()).toEqual(inHook.slice().sort());
568
+ });
569
+
570
+ /*
571
+ * A stub for a seeder that no longer exists is dead weight, and
572
+ * jest.spyOn would throw on the missing method rather than skip it.
573
+ */
574
+ test("every seeder stubbed here is a real method on the service", () => {
575
+ for (const seeder of DEFAULT_SEEDERS) {
576
+ expect(
577
+ typeof (ProjectService as unknown as Record<string, unknown>)[seeder],
578
+ ).toBe("function");
579
+ }
580
+ });
581
+ });
519
582
  });
@@ -0,0 +1,214 @@
1
+ import NetworkSiteTypeService from "../../../Server/Services/NetworkSiteTypeService";
2
+ import ProjectService from "../../../Server/Services/ProjectService";
3
+ import NetworkSiteType from "../../../Models/DatabaseModels/NetworkSiteType";
4
+ import Project from "../../../Models/DatabaseModels/Project";
5
+ import DefaultNetworkSiteType from "../../../Types/NetworkSite/DefaultNetworkSiteType";
6
+ import {
7
+ DefaultNetworkSiteTypeCreationOrder,
8
+ DefaultNetworkSiteTypeParent,
9
+ } from "../../../Types/NetworkSite/DefaultNetworkSiteTypeHierarchy";
10
+ import ObjectID from "../../../Types/ObjectID";
11
+ import LIMIT_MAX from "../../../Types/Database/LimitMax";
12
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
13
+ import { afterEach, describe, expect, it } from "@jest/globals";
14
+
15
+ const PROJECT_ID: ObjectID = new ObjectID(
16
+ "11111111-1111-4111-8111-111111111111",
17
+ );
18
+
19
+ function typeId(index: number): ObjectID {
20
+ return new ObjectID(
21
+ `aaaaaaaa-aaaa-4aaa-8aaa-${index.toString().padStart(12, "0")}`,
22
+ );
23
+ }
24
+
25
+ function project(): Project {
26
+ const project: Project = new Project();
27
+ project.id = PROJECT_ID;
28
+ return project;
29
+ }
30
+
31
+ function existingType(
32
+ name: DefaultNetworkSiteType,
33
+ index: number,
34
+ ): NetworkSiteType {
35
+ const networkSiteType: NetworkSiteType = new NetworkSiteType();
36
+ networkSiteType.id = typeId(index);
37
+ networkSiteType.name = name;
38
+ networkSiteType.projectId = PROJECT_ID;
39
+ return networkSiteType;
40
+ }
41
+
42
+ function mockCreatesWithIds(startingIndex: number = 1): jest.SpyInstance {
43
+ let index: number = startingIndex;
44
+
45
+ return jest
46
+ .spyOn(NetworkSiteTypeService, "create")
47
+ .mockImplementation(async (createBy: any) => {
48
+ createBy.data.id = typeId(index);
49
+ index++;
50
+ return createBy.data;
51
+ });
52
+ }
53
+
54
+ afterEach(() => {
55
+ jest.restoreAllMocks();
56
+ });
57
+
58
+ describe("ProjectService default Network Site Type hierarchy", () => {
59
+ it("creates defaults parent-first with the explicit hierarchy and sibling orders", async () => {
60
+ jest.spyOn(NetworkSiteTypeService, "findBy").mockResolvedValue([]);
61
+ const createSpy: jest.SpyInstance = mockCreatesWithIds();
62
+
63
+ await ProjectService.addDefaultNetworkSiteTypes(project());
64
+
65
+ const created: Array<NetworkSiteType> = createSpy.mock.calls.map(
66
+ (call: Array<any>) => {
67
+ return call[0].data as NetworkSiteType;
68
+ },
69
+ );
70
+ const byName: Map<DefaultNetworkSiteType, NetworkSiteType> = new Map(
71
+ created.map((networkSiteType: NetworkSiteType) => {
72
+ return [
73
+ networkSiteType.name as DefaultNetworkSiteType,
74
+ networkSiteType,
75
+ ];
76
+ }),
77
+ );
78
+
79
+ expect(
80
+ created.map((networkSiteType: NetworkSiteType) => {
81
+ return networkSiteType.name;
82
+ }),
83
+ ).toEqual(DefaultNetworkSiteTypeCreationOrder);
84
+
85
+ for (const name of DefaultNetworkSiteTypeCreationOrder) {
86
+ const networkSiteType: NetworkSiteType = byName.get(name)!;
87
+ const parentName: DefaultNetworkSiteType | null =
88
+ DefaultNetworkSiteTypeParent[name];
89
+
90
+ expect(networkSiteType.projectId).toEqual(PROJECT_ID);
91
+ expect(networkSiteType.isUnitLevel).toBe(
92
+ name === DefaultNetworkSiteType.Unit,
93
+ );
94
+
95
+ if (parentName) {
96
+ expect(networkSiteType.parentNetworkSiteTypeId).toEqual(
97
+ byName.get(parentName)!.id,
98
+ );
99
+ expect(networkSiteType.order).toBe(1);
100
+ } else {
101
+ expect(networkSiteType.parentNetworkSiteTypeId).toBeUndefined();
102
+ }
103
+ }
104
+
105
+ expect(byName.get(DefaultNetworkSiteType.AccountType)!.order).toBe(1);
106
+ expect(byName.get(DefaultNetworkSiteType.DataCenter)!.order).toBe(2);
107
+ expect(byName.get(DefaultNetworkSiteType.Other)!.order).toBe(3);
108
+ });
109
+
110
+ it("can seed legacy defaults without pre-empting the concrete-tree backfill", async () => {
111
+ jest.spyOn(NetworkSiteTypeService, "findBy").mockResolvedValue([]);
112
+ const createSpy: jest.SpyInstance = mockCreatesWithIds();
113
+
114
+ await ProjectService.addDefaultNetworkSiteTypes(project(), {
115
+ setParentRelationships: false,
116
+ });
117
+
118
+ const created: Array<NetworkSiteType> = createSpy.mock.calls.map(
119
+ (call: Array<any>) => {
120
+ return call[0].data as NetworkSiteType;
121
+ },
122
+ );
123
+
124
+ expect(created).toHaveLength(DefaultNetworkSiteTypeCreationOrder.length);
125
+ expect(
126
+ created.every((networkSiteType: NetworkSiteType): boolean => {
127
+ return !networkSiteType.parentNetworkSiteTypeId;
128
+ }),
129
+ ).toBe(true);
130
+ expect(
131
+ created.map((networkSiteType: NetworkSiteType) => {
132
+ return networkSiteType.order;
133
+ }),
134
+ ).toEqual([1, 2, 3, 4, 5, 6, 7]);
135
+ });
136
+
137
+ it("is idempotent when every default already exists", async () => {
138
+ jest.spyOn(NetworkSiteTypeService, "findBy").mockResolvedValue(
139
+ DefaultNetworkSiteTypeCreationOrder.map(
140
+ (name: DefaultNetworkSiteType, index: number) => {
141
+ return existingType(name, index + 1);
142
+ },
143
+ ),
144
+ );
145
+ const createSpy: jest.SpyInstance = jest.spyOn(
146
+ NetworkSiteTypeService,
147
+ "create",
148
+ );
149
+
150
+ await ProjectService.addDefaultNetworkSiteTypes(project());
151
+
152
+ expect(createSpy).not.toHaveBeenCalled();
153
+ });
154
+
155
+ it("reads every type page before deciding which defaults are missing", async () => {
156
+ const customType: NetworkSiteType = new NetworkSiteType(typeId(98));
157
+ customType.name = "Custom type";
158
+ customType.projectId = PROJECT_ID;
159
+ const existingUnit: NetworkSiteType = existingType(
160
+ DefaultNetworkSiteType.Unit,
161
+ 99,
162
+ );
163
+ const findSpy: jest.SpyInstance = jest
164
+ .spyOn(NetworkSiteTypeService, "findBy")
165
+ .mockResolvedValueOnce(
166
+ Array.from({ length: LIMIT_MAX }, () => {
167
+ return customType;
168
+ }),
169
+ )
170
+ .mockResolvedValueOnce([existingUnit]);
171
+ const createSpy: jest.SpyInstance = mockCreatesWithIds();
172
+
173
+ await ProjectService.addDefaultNetworkSiteTypes(project());
174
+
175
+ expect(findSpy).toHaveBeenCalledTimes(2);
176
+ expect(findSpy.mock.calls[0]![0]).toEqual(
177
+ expect.objectContaining({
178
+ skip: 0,
179
+ limit: LIMIT_MAX,
180
+ sort: { _id: SortOrder.Ascending },
181
+ }),
182
+ );
183
+ expect(findSpy.mock.calls[1]![0]).toEqual(
184
+ expect.objectContaining({ skip: LIMIT_MAX, limit: LIMIT_MAX }),
185
+ );
186
+ expect(
187
+ createSpy.mock.calls.some((call: Array<any>): boolean => {
188
+ return call[0].data.name === DefaultNetworkSiteType.Unit;
189
+ }),
190
+ ).toBe(false);
191
+ });
192
+
193
+ it("resolves a newly created child against an existing default parent", async () => {
194
+ const existingAccount: NetworkSiteType = existingType(
195
+ DefaultNetworkSiteType.AccountType,
196
+ 99,
197
+ );
198
+ jest
199
+ .spyOn(NetworkSiteTypeService, "findBy")
200
+ .mockResolvedValue([existingAccount]);
201
+ const createSpy: jest.SpyInstance = mockCreatesWithIds(1);
202
+
203
+ await ProjectService.addDefaultNetworkSiteTypes(project());
204
+
205
+ const region: NetworkSiteType = createSpy.mock.calls.find(
206
+ (call: Array<any>) => {
207
+ return call[0].data.name === DefaultNetworkSiteType.Region;
208
+ },
209
+ )![0].data;
210
+
211
+ expect(region.parentNetworkSiteTypeId).toEqual(existingAccount.id);
212
+ expect(createSpy).toHaveBeenCalledTimes(6);
213
+ });
214
+ });
@@ -0,0 +1,369 @@
1
+ import ScheduledMaintenance from "../../../Models/DatabaseModels/ScheduledMaintenance";
2
+ import ProjectCallSMSConfig from "../../../Models/DatabaseModels/ProjectCallSMSConfig";
3
+ import ProjectSmtpConfig from "../../../Models/DatabaseModels/ProjectSmtpConfig";
4
+ import StatusPage from "../../../Models/DatabaseModels/StatusPage";
5
+ import StatusPageSubscriber from "../../../Models/DatabaseModels/StatusPageSubscriber";
6
+ import StatusPageSubscriberNotificationTemplate from "../../../Models/DatabaseModels/StatusPageSubscriberNotificationTemplate";
7
+ import DatabaseConfig from "../../../Server/DatabaseConfig";
8
+ import MailService from "../../../Server/Services/MailService";
9
+ import ProjectCallSMSConfigService from "../../../Server/Services/ProjectCallSMSConfigService";
10
+ import ProjectSmtpConfigService from "../../../Server/Services/ProjectSmtpConfigService";
11
+ import ScheduledMaintenanceService from "../../../Server/Services/ScheduledMaintenanceService";
12
+ import SmsService from "../../../Server/Services/SmsService";
13
+ import StatusPageResourceService from "../../../Server/Services/StatusPageResourceService";
14
+ import StatusPageService from "../../../Server/Services/StatusPageService";
15
+ import StatusPageSubscriberNotificationTemplateService from "../../../Server/Services/StatusPageSubscriberNotificationTemplateService";
16
+ import StatusPageSubscriberService from "../../../Server/Services/StatusPageSubscriberService";
17
+ import Markdown from "../../../Server/Types/Markdown";
18
+ import SlackUtil from "../../../Server/Utils/Workspace/Slack/Slack";
19
+ import StatusPageSubscriberWebhookUtil from "../../../Server/Utils/StatusPageSubscriberWebhook";
20
+ import Hostname from "../../../Types/API/Hostname";
21
+ import HTTPResponse from "../../../Types/API/HTTPResponse";
22
+ import Protocol from "../../../Types/API/Protocol";
23
+ import URL from "../../../Types/API/URL";
24
+ import OneUptimeDate from "../../../Types/Date";
25
+ import { JSONObject } from "../../../Types/JSON";
26
+ import Email from "../../../Types/Email";
27
+ import Phone from "../../../Types/Phone";
28
+ import ObjectID from "../../../Types/ObjectID";
29
+ import StatusPageSubscriberNotificationMethod from "../../../Types/StatusPage/StatusPageSubscriberNotificationMethod";
30
+ import {
31
+ afterEach,
32
+ beforeEach,
33
+ describe,
34
+ expect,
35
+ jest,
36
+ test,
37
+ } from "@jest/globals";
38
+
39
+ /*
40
+ * The other half of GitHub issue #3545.
41
+ *
42
+ * The worker jobs did not select `endsAt`, so this service received events
43
+ * with the end time missing and rendered `{{scheduledEndTime}}` as an empty
44
+ * string — while `{{scheduledStartTime}}` rendered fine, which is what made
45
+ * the bug look like a template problem rather than a query problem.
46
+ *
47
+ * The worker suites pin that `endsAt` now arrives. This suite pins the
48
+ * consequence: given an event that carries `endsAt`, every channel that
49
+ * advertises `{{scheduledEndTime}}` to template authors — custom email, SMS
50
+ * and Slack templates, plus the subscriber webhook payload — actually renders
51
+ * the end time; and given an event without one, they degrade to an empty
52
+ * string rather than printing "undefined" at a subscriber.
53
+ *
54
+ * Everything the service talks to is a `jest.spyOn`: no database, no mail
55
+ * server, no Slack. What is under test is this service's own rendering, driven
56
+ * through the real `compileTemplate`.
57
+ */
58
+
59
+ const PROJECT_ID: ObjectID = new ObjectID(
60
+ "11111111-1111-4111-8111-111111111111",
61
+ );
62
+ const STATUS_PAGE_ID: ObjectID = new ObjectID(
63
+ "22222222-2222-4222-8222-222222222222",
64
+ );
65
+ const SUBSCRIBER_ID: ObjectID = new ObjectID(
66
+ "33333333-3333-4333-8333-333333333333",
67
+ );
68
+ const EVENT_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
69
+
70
+ const STARTS_AT: Date = new Date("2024-03-04T06:08:00.000Z");
71
+ const ENDS_AT: Date = new Date("2024-03-04T08:00:00.000Z");
72
+
73
+ const TEMPLATE_BODY: string =
74
+ "Start: {{scheduledStartTime}} | End: {{scheduledEndTime}}";
75
+
76
+ // What the template author expects to see rendered, in the service's own format.
77
+ const EXPECTED_END: string =
78
+ OneUptimeDate.getDateAsUserFriendlyFormattedString(ENDS_AT);
79
+ const EXPECTED_START: string =
80
+ OneUptimeDate.getDateAsUserFriendlyFormattedString(STARTS_AT);
81
+
82
+ // Every outbound channel here resolves an HTTPResponse rather than throwing.
83
+ function accepted(): HTTPResponse<JSONObject> {
84
+ return new HTTPResponse<JSONObject>(200, {}, {});
85
+ }
86
+
87
+ function scheduledEvent(endsAt?: Date): ScheduledMaintenance {
88
+ const event: ScheduledMaintenance = new ScheduledMaintenance();
89
+
90
+ event._id = EVENT_ID.toString();
91
+ event.projectId = PROJECT_ID;
92
+ event.title = "Quarterly database failover drill";
93
+ event.description = "Failing over the primary.";
94
+ event.startsAt = STARTS_AT;
95
+
96
+ if (endsAt) {
97
+ event.endsAt = endsAt;
98
+ }
99
+
100
+ const statusPage: StatusPage = new StatusPage();
101
+ statusPage._id = STATUS_PAGE_ID.toString();
102
+ event.statusPages = [statusPage];
103
+
104
+ return event;
105
+ }
106
+
107
+ function statusPageWithCustomProviders(): StatusPage {
108
+ const statusPage: StatusPage = new StatusPage();
109
+
110
+ statusPage._id = STATUS_PAGE_ID.toString();
111
+ statusPage.projectId = PROJECT_ID;
112
+ statusPage.name = "Acme Status";
113
+ statusPage.pageTitle = "Acme Status";
114
+ statusPage.isPublicStatusPage = true;
115
+ statusPage.showScheduledMaintenanceEventsOnStatusPage = true;
116
+ statusPage.allowSubscribersToChooseResources = false;
117
+ statusPage.allowSubscribersToChooseEventTypes = false;
118
+ statusPage.subscriberTimezones = [];
119
+
120
+ /*
121
+ * Custom email and SMS templates are only honoured when the status page
122
+ * brings its own SMTP/Twilio credentials, so both configs are required for
123
+ * this suite to exercise the custom-template path at all.
124
+ */
125
+ const smtpConfig: ProjectSmtpConfig = new ProjectSmtpConfig();
126
+ smtpConfig._id = "55555555-5555-4555-8555-555555555555";
127
+ statusPage.smtpConfig = smtpConfig;
128
+
129
+ const callSmsConfig: ProjectCallSMSConfig = new ProjectCallSMSConfig();
130
+ callSmsConfig._id = "66666666-6666-4666-8666-666666666666";
131
+ statusPage.callSmsConfig = callSmsConfig;
132
+
133
+ return statusPage;
134
+ }
135
+
136
+ function subscriberOnEveryChannel(): StatusPageSubscriber {
137
+ const subscriber: StatusPageSubscriber = new StatusPageSubscriber();
138
+
139
+ subscriber._id = SUBSCRIBER_ID.toString();
140
+ subscriber.statusPageId = STATUS_PAGE_ID;
141
+ subscriber.isUnsubscribed = false;
142
+ subscriber.isSubscribedToAllResources = true;
143
+ subscriber.isSubscribedToAllEventTypes = true;
144
+ subscriber.subscriberEmail = new Email("subscriber@example.com");
145
+ subscriber.subscriberPhone = new Phone("+15558675309");
146
+ subscriber.slackIncomingWebhookUrl = URL.fromString(
147
+ "https://hooks.slack.com/services/T/B/X",
148
+ );
149
+ subscriber.subscriberWebhook = URL.fromString(
150
+ "https://hooks.example.com/subscriber",
151
+ );
152
+
153
+ return subscriber;
154
+ }
155
+
156
+ function customTemplate(
157
+ method: StatusPageSubscriberNotificationMethod,
158
+ ): StatusPageSubscriberNotificationTemplate {
159
+ const template: StatusPageSubscriberNotificationTemplate =
160
+ new StatusPageSubscriberNotificationTemplate();
161
+
162
+ template._id = `template-${method}`;
163
+ template.templateBody = TEMPLATE_BODY;
164
+ template.emailSubject = "Window ends {{scheduledEndTime}}";
165
+ template.notificationMethod = method;
166
+
167
+ return template;
168
+ }
169
+
170
+ // The rendered body of the one custom email this run produced.
171
+ function sentEmailBody(): string {
172
+ const call: Array<unknown> = (MailService.sendMail as unknown as jest.Mock)
173
+ .mock.calls[0]!;
174
+
175
+ return String((call[0] as { vars: { body: string } }).vars.body);
176
+ }
177
+
178
+ function sentEmailSubject(): string {
179
+ const call: Array<unknown> = (MailService.sendMail as unknown as jest.Mock)
180
+ .mock.calls[0]!;
181
+
182
+ return String((call[0] as { subject: string }).subject);
183
+ }
184
+
185
+ function sentSmsMessage(): string {
186
+ const call: Array<unknown> = (SmsService.sendSms as unknown as jest.Mock).mock
187
+ .calls[0]!;
188
+
189
+ return String((call[0] as { message: string }).message);
190
+ }
191
+
192
+ function sentSlackMessage(): string {
193
+ return String(
194
+ (SlackUtil.convertMarkdownToSlackRichText as unknown as jest.Mock).mock
195
+ .calls[0]![0],
196
+ );
197
+ }
198
+
199
+ function sentWebhookPayload(): Record<string, string> {
200
+ const call: Array<unknown> = (
201
+ StatusPageSubscriberWebhookUtil.sendWebhookNotification as unknown as jest.Mock
202
+ ).mock.calls[0]!;
203
+
204
+ return (call[0] as { payload: { data: Record<string, string> } }).payload
205
+ .data;
206
+ }
207
+
208
+ describe("scheduled maintenance subscriber notifications: {{scheduledEndTime}}", () => {
209
+ beforeEach(() => {
210
+ jest
211
+ .spyOn(DatabaseConfig, "getHost")
212
+ .mockResolvedValue(new Hostname("oneuptime.com"));
213
+ jest
214
+ .spyOn(DatabaseConfig, "getHttpProtocol")
215
+ .mockResolvedValue(Protocol.HTTPS);
216
+
217
+ jest
218
+ .spyOn(StatusPageResourceService, "findByMonitors")
219
+ .mockResolvedValue([]);
220
+
221
+ jest
222
+ .spyOn(StatusPageSubscriberService, "getStatusPagesToSendNotification")
223
+ .mockResolvedValue([statusPageWithCustomProviders()]);
224
+
225
+ jest
226
+ .spyOn(StatusPageSubscriberService, "getSubscribersByStatusPage")
227
+ .mockResolvedValue([subscriberOnEveryChannel()]);
228
+
229
+ jest
230
+ .spyOn(StatusPageService, "getStatusPageURL")
231
+ .mockResolvedValue("https://status.example.com");
232
+
233
+ jest
234
+ .spyOn(
235
+ StatusPageSubscriberNotificationTemplateService,
236
+ "getTemplateForStatusPage",
237
+ )
238
+ .mockImplementation(
239
+ async (data: {
240
+ notificationMethod: StatusPageSubscriberNotificationMethod;
241
+ }): Promise<StatusPageSubscriberNotificationTemplate | null> => {
242
+ return customTemplate(data.notificationMethod);
243
+ },
244
+ );
245
+
246
+ jest
247
+ .spyOn(ProjectSmtpConfigService, "toEmailServer")
248
+ .mockReturnValue(undefined);
249
+ jest
250
+ .spyOn(ProjectCallSMSConfigService, "toTwilioConfig")
251
+ .mockReturnValue(undefined);
252
+
253
+ jest
254
+ .spyOn(Markdown, "convertToHTML")
255
+ .mockImplementation(async (markdown: string): Promise<string> => {
256
+ return markdown;
257
+ });
258
+
259
+ jest.spyOn(MailService, "sendMail").mockResolvedValue(accepted());
260
+ jest.spyOn(SmsService, "sendSms").mockResolvedValue(accepted());
261
+ jest
262
+ .spyOn(SlackUtil, "sendMessageToChannelViaIncomingWebhook")
263
+ .mockResolvedValue(undefined as never);
264
+ jest
265
+ .spyOn(SlackUtil, "convertMarkdownToSlackRichText")
266
+ .mockImplementation((markdown: string): string => {
267
+ return markdown;
268
+ });
269
+ jest
270
+ .spyOn(StatusPageSubscriberWebhookUtil, "sendWebhookNotification")
271
+ .mockResolvedValue(accepted());
272
+ });
273
+
274
+ afterEach(() => {
275
+ jest.restoreAllMocks();
276
+ });
277
+
278
+ test("renders the end time in a custom email body", async () => {
279
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
280
+ scheduledEvent(ENDS_AT),
281
+ ]);
282
+
283
+ /*
284
+ * Guards the fixture itself: an empty EXPECTED_END would make every
285
+ * assertion in this file pass on the very bug it exists to catch.
286
+ */
287
+ expect(EXPECTED_END).not.toBe("");
288
+
289
+ expect(MailService.sendMail).toHaveBeenCalledTimes(1);
290
+ expect(sentEmailBody()).toBe(
291
+ `Start: ${EXPECTED_START} | End: ${EXPECTED_END}`,
292
+ );
293
+ });
294
+
295
+ test("renders the end time in a custom email subject", async () => {
296
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
297
+ scheduledEvent(ENDS_AT),
298
+ ]);
299
+
300
+ expect(sentEmailSubject()).toBe(`Window ends ${EXPECTED_END}`);
301
+ });
302
+
303
+ test("renders the end time in a custom SMS template", async () => {
304
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
305
+ scheduledEvent(ENDS_AT),
306
+ ]);
307
+
308
+ expect(SmsService.sendSms).toHaveBeenCalledTimes(1);
309
+ expect(sentSmsMessage()).toBe(
310
+ `Start: ${EXPECTED_START} | End: ${EXPECTED_END}`,
311
+ );
312
+ });
313
+
314
+ test("renders the end time in a custom Slack template", async () => {
315
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
316
+ scheduledEvent(ENDS_AT),
317
+ ]);
318
+
319
+ expect(sentSlackMessage()).toBe(
320
+ `Start: ${EXPECTED_START} | End: ${EXPECTED_END}`,
321
+ );
322
+ });
323
+
324
+ test("sends the end time in the subscriber webhook payload", async () => {
325
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
326
+ scheduledEvent(ENDS_AT),
327
+ ]);
328
+
329
+ expect(sentWebhookPayload()["scheduledEndTime"]).toBe(EXPECTED_END);
330
+ expect(sentWebhookPayload()["scheduledStartTime"]).toBe(EXPECTED_START);
331
+ });
332
+
333
+ test("renders an empty end time — never 'undefined' — for an open-ended event", async () => {
334
+ /*
335
+ * An event with no end time is legitimate. The subscriber should see a
336
+ * blank, not the string "undefined": this is the behaviour the bug made
337
+ * universal, and it has to survive as the genuine no-end-time case.
338
+ */
339
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
340
+ scheduledEvent(undefined),
341
+ ]);
342
+
343
+ expect(sentEmailBody()).toBe(`Start: ${EXPECTED_START} | End: `);
344
+ expect(sentSmsMessage()).toBe(`Start: ${EXPECTED_START} | End: `);
345
+ expect(sentWebhookPayload()["scheduledEndTime"]).toBe("");
346
+ });
347
+
348
+ test("renders each event's own end time when several are notified at once", async () => {
349
+ const laterEnd: Date = new Date("2024-03-05T09:30:00.000Z");
350
+
351
+ await ScheduledMaintenanceService.notififySubscribersOnEventScheduled([
352
+ scheduledEvent(ENDS_AT),
353
+ scheduledEvent(laterEnd),
354
+ ]);
355
+
356
+ const bodies: Array<string> = (
357
+ MailService.sendMail as unknown as jest.Mock
358
+ ).mock.calls.map((call: Array<unknown>) => {
359
+ return String((call[0] as { vars: { body: string } }).vars.body);
360
+ });
361
+
362
+ expect(bodies).toEqual([
363
+ `Start: ${EXPECTED_START} | End: ${EXPECTED_END}`,
364
+ `Start: ${EXPECTED_START} | End: ${OneUptimeDate.getDateAsUserFriendlyFormattedString(
365
+ laterEnd,
366
+ )}`,
367
+ ]);
368
+ });
369
+ });