@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.
- package/Models/AnalyticsModels/Span.ts +14 -0
- package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/Index.ts +10 -0
- package/Models/DatabaseModels/Monitor.ts +76 -0
- package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
- package/Models/DatabaseModels/NetworkDevice.ts +176 -1
- package/Models/DatabaseModels/NetworkSite.ts +201 -2
- package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
- package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
- package/Models/DatabaseModels/TelemetryException.ts +119 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
- package/Server/API/EnterpriseLicenseAPI.ts +391 -64
- package/Server/API/LlmProviderAPI.ts +137 -22
- package/Server/EnvironmentConfig.ts +14 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Infrastructure/QueueWorker.ts +38 -8
- package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
- package/Server/Middleware/ProjectAuthorization.ts +11 -0
- package/Server/Middleware/SCIMAuthorization.ts +12 -0
- package/Server/Middleware/TelemetryIngest.ts +11 -0
- package/Server/Services/AIBillingService.ts +101 -27
- package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/MonitorService.ts +143 -21
- package/Server/Services/MonitorStatusTimelineService.ts +150 -8
- package/Server/Services/MonitorTemplateService.ts +217 -1
- package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
- package/Server/Services/NetworkAlertPolicyService.ts +944 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +9 -10
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
- package/Server/Services/NetworkDeviceService.ts +1032 -73
- package/Server/Services/NetworkSiteService.ts +1502 -129
- package/Server/Services/NetworkSiteTypeService.ts +1216 -0
- package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
- package/Server/Services/NotificationService.ts +118 -28
- package/Server/Services/ProjectService.ts +105 -48
- package/Server/Services/StatusPagePrivateUserService.ts +103 -3
- package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
- package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
- package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
- package/Server/Services/UserNotificationSettingService.ts +62 -25
- package/Server/Services/UserService.ts +95 -0
- package/Server/Types/Database/QueryHelper.ts +2 -2
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
- package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
- package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
- package/Server/Utils/DataSource/HttpFetch.ts +9 -2
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
- package/Server/Utils/LLM/LLMService.ts +78 -0
- package/Server/Utils/LogRedaction.ts +8 -0
- package/Server/Utils/Logger.ts +79 -1
- package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
- package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
- package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
- package/Server/Utils/OutboundUserAgent.ts +152 -0
- package/Server/Utils/StartServer.ts +51 -19
- package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
- package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
- package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
- package/Server/Utils/Telemetry.ts +198 -51
- package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
- package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
- package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -9
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
- package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
- package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
- package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
- package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
- package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
- package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
- package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
- package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
- package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
- package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
- package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
- package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
- package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
- package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
- package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
- package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
- package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
- package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
- package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
- package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
- package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
- package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +47 -4
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
- package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
- package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
- package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
- package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
- package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
- package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
- package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
- package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
- package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
- package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
- package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +856 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +102 -1
- package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
- package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
- package/Tests/Server/Utils/Captcha.test.ts +422 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
- package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
- package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
- package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
- package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
- package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
- package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
- package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
- package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
- package/Tests/Server/Utils/Telemetry.test.ts +456 -66
- package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
- package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
- package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
- package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
- package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
- package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
- package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
- package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
- package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
- package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
- package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
- package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
- package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
- package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
- package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
- package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
- package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
- package/Types/AI/ExceptionAIClassification.ts +10 -24
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
- package/Types/Exception/ApiException.ts +10 -0
- package/Types/Exception/BadDataException.ts +11 -0
- package/Types/Exception/BadRequestException.ts +11 -0
- package/Types/Exception/Exception.ts +65 -0
- package/Types/Exception/ForbiddenException.ts +10 -0
- package/Types/Exception/NotAuthenticatedException.ts +10 -0
- package/Types/Exception/NotAuthorizedException.ts +10 -0
- package/Types/Exception/NotFoundException.ts +11 -0
- package/Types/Exception/PayloadTooLargeException.ts +11 -0
- package/Types/Exception/PaymentRequiredException.ts +10 -0
- package/Types/Exception/ServiceUnavailableException.ts +10 -0
- package/Types/Exception/SsoAuthorizationException.ts +10 -0
- package/Types/Exception/TenantNotFoundException.ts +11 -0
- package/Types/Exception/TimeoutException.ts +10 -0
- package/Types/Exception/TooManyRequestsException.ts +10 -0
- package/Types/Exception/UnableToReachServer.ts +10 -0
- package/Types/Exception/WebsiteRequestException.ts +10 -0
- package/Types/Monitor/CriteriaFilter.ts +60 -2
- package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
- package/Types/Monitor/MonitorMetricType.ts +71 -0
- package/Types/Monitor/MonitorStep.ts +76 -0
- package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
- package/Types/Monitor/MonitorType.ts +47 -1
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
- package/Types/Monitor/SqlConnectionConfig.ts +31 -0
- package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
- package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
- package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
- package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
- package/Types/Permission.ts +90 -0
- package/Types/Probe/ProbeMonitorResponse.ts +16 -0
- package/Types/Telemetry/ErrorClass.ts +274 -0
- package/Types/Telemetry/UnitOfWork.ts +59 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
- package/UI/Components/Modal/Modal.tsx +2 -8
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
- package/UI/Components/SideMenu/SideMenu.tsx +123 -5
- package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
- package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
- package/UI/Components/SideOver/SideOver.tsx +21 -20
- package/UI/Utils/PageScrollLock.ts +79 -3
- package/UI/Utils/PermissionGate.ts +61 -0
- package/UI/Utils/SensitiveUrlToken.ts +112 -0
- package/UI/Utils/TestLLMProvider.ts +11 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- package/Utils/Monitor/MonitorMetricType.ts +153 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
- package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
- package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
- package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
- package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
- package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
- package/build/dist/Models/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +108 -13
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +12 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +11 -0
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIBillingService.js +70 -16
- package/build/dist/Server/Services/AIBillingService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +119 -21
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +10 -9
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
- package/build/dist/Server/Services/NotificationService.js +80 -17
- package/build/dist/Server/Services/NotificationService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +66 -30
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +46 -20
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +90 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +91 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
- package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +8 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +63 -1
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +37 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +38 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +162 -46
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
- package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
- package/build/dist/Types/Exception/ApiException.js +9 -0
- package/build/dist/Types/Exception/ApiException.js.map +1 -1
- package/build/dist/Types/Exception/BadDataException.js +10 -0
- package/build/dist/Types/Exception/BadDataException.js.map +1 -1
- package/build/dist/Types/Exception/BadRequestException.js +10 -0
- package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
- package/build/dist/Types/Exception/Exception.js +56 -0
- package/build/dist/Types/Exception/Exception.js.map +1 -1
- package/build/dist/Types/Exception/ForbiddenException.js +9 -0
- package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
- package/build/dist/Types/Exception/NotFoundException.js +10 -0
- package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
- package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
- package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
- package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
- package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
- package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
- package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/TimeoutException.js +9 -0
- package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
- package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
- package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
- package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
- package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
- package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +54 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +45 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
- package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
- package/build/dist/Types/Permission.js +80 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
- package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -7
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +31 -3
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +42 -1
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
- package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
- package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
- package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
- 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
|