@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,802 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Contract under test: WHERE a monitor status change is bridged to the
|
|
3
|
+
* network-site rollup engine (NetworkSiteService.onMonitorStatusChanged),
|
|
4
|
+
* which is what stamps a bound NetworkDevice's currentMonitorStatusId and
|
|
5
|
+
* isReachable and refreshes its site chain.
|
|
6
|
+
*
|
|
7
|
+
* The pre-existing bug: the only call to that bridge lived inside
|
|
8
|
+
* MonitorService.changeMonitorStatus. A PROBE result never goes through
|
|
9
|
+
* changeMonitorStatus - it goes MonitorResource ->
|
|
10
|
+
* MonitorStatusTimelineService.create -> onCreateSuccess ->
|
|
11
|
+
* MonitorService.updateOneBy({ currentMonitorStatusId }) with ROOT props,
|
|
12
|
+
* and MonitorService.onUpdateSuccess only calls changeMonitorStatus when
|
|
13
|
+
* props.tenantId is set. So a ping monitor going down moved the monitor's
|
|
14
|
+
* status and left every device bound to it exactly where it was; devices
|
|
15
|
+
* only ever moved on manual, incident and maintenance status changes.
|
|
16
|
+
*
|
|
17
|
+
* What is pinned here:
|
|
18
|
+
*
|
|
19
|
+
* - MonitorStatusTimelineService.create bridges a NEW CURRENT row (no
|
|
20
|
+
* endsAt) exactly once, with root props and no tenantId - the probe
|
|
21
|
+
* path's exact shape - and does not bridge a row that is already closed
|
|
22
|
+
* (an endsAt: a backfilled historical row that is not the current
|
|
23
|
+
* status). It bridges AFTER super.create has resolved and the
|
|
24
|
+
* per-monitor mutex has been released: the bridge stamps every bound
|
|
25
|
+
* device and recomputes each site chain (alerts, workspace
|
|
26
|
+
* notifications), and holding the lock across that would refuse
|
|
27
|
+
* concurrent status writes for the monitor past the semaphore's
|
|
28
|
+
* acquire timeout,
|
|
29
|
+
* - onCreateSuccess (which runs UNDER that mutex) writes the monitor's
|
|
30
|
+
* currentMonitorStatusId and does NOT call the bridge itself,
|
|
31
|
+
* - onDeleteSuccess bridges the SURVIVING latest status after a row is
|
|
32
|
+
* deleted,
|
|
33
|
+
* - MonitorService.refreshMonitorCurrentStatus bridges only when it
|
|
34
|
+
* actually moved the id,
|
|
35
|
+
* - changeMonitorStatus no longer calls the bridge itself: its timeline
|
|
36
|
+
* create reaches MonitorStatusTimelineService.create's bridge, so
|
|
37
|
+
* keeping both stamped every device twice,
|
|
38
|
+
* - a bridge that throws never fails the status write it follows.
|
|
39
|
+
*
|
|
40
|
+
* Everything below the service boundary is spied - no database. Semaphore is
|
|
41
|
+
* mocked at the module boundary (as MonitorStatusTimelineService.test.ts
|
|
42
|
+
* does) so create() can run its lock -> super.create -> release -> bridge
|
|
43
|
+
* sequence without Redis.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
const lockMock: jest.Mock = jest.fn();
|
|
47
|
+
const releaseMock: jest.Mock = jest.fn();
|
|
48
|
+
|
|
49
|
+
jest.mock("../../../Server/Infrastructure/Semaphore", () => {
|
|
50
|
+
return {
|
|
51
|
+
__esModule: true,
|
|
52
|
+
default: {
|
|
53
|
+
lock: (...args: Array<unknown>) => {
|
|
54
|
+
return lockMock(...args);
|
|
55
|
+
},
|
|
56
|
+
release: (...args: Array<unknown>) => {
|
|
57
|
+
return releaseMock(...args);
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
import MonitorStatusTimelineService from "../../../Server/Services/MonitorStatusTimelineService";
|
|
64
|
+
import DatabaseService from "../../../Server/Services/DatabaseService";
|
|
65
|
+
import MonitorService from "../../../Server/Services/MonitorService";
|
|
66
|
+
import NetworkSiteService from "../../../Server/Services/NetworkSiteService";
|
|
67
|
+
import logger from "../../../Server/Utils/Logger";
|
|
68
|
+
import MonitorStatusTimeline from "../../../Models/DatabaseModels/MonitorStatusTimeline";
|
|
69
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
70
|
+
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
71
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
72
|
+
import DeleteBy from "../../../Server/Types/Database/DeleteBy";
|
|
73
|
+
import { OnCreate, OnDelete } from "../../../Server/Types/Database/Hooks";
|
|
74
|
+
import fs from "fs";
|
|
75
|
+
import path from "path";
|
|
76
|
+
import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
|
|
77
|
+
|
|
78
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
79
|
+
"22222222-2222-4222-8222-222222222222",
|
|
80
|
+
);
|
|
81
|
+
const MONITOR_ID: ObjectID = new ObjectID(
|
|
82
|
+
"44444444-4444-4444-8444-444444444444",
|
|
83
|
+
);
|
|
84
|
+
const ROW_ID: ObjectID = new ObjectID("11111111-1111-4111-8111-111111111111");
|
|
85
|
+
const OPERATIONAL_STATUS_ID: ObjectID = new ObjectID(
|
|
86
|
+
"55555555-5555-4555-8555-555555555555",
|
|
87
|
+
);
|
|
88
|
+
const OFFLINE_STATUS_ID: ObjectID = new ObjectID(
|
|
89
|
+
"66666666-6666-4666-8666-666666666666",
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// The probe path's props: root, and deliberately NO tenantId.
|
|
93
|
+
const ROOT_PROPS: DatabaseCommonInteractionProps = {
|
|
94
|
+
isRoot: true,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
function fakeTimelineRow(data: {
|
|
98
|
+
monitorStatusId: ObjectID;
|
|
99
|
+
projectId?: ObjectID | undefined;
|
|
100
|
+
endsAt?: Date | undefined;
|
|
101
|
+
}): MonitorStatusTimeline {
|
|
102
|
+
const row: MonitorStatusTimeline = new MonitorStatusTimeline();
|
|
103
|
+
row.id = ROW_ID;
|
|
104
|
+
row.monitorId = MONITOR_ID;
|
|
105
|
+
row.monitorStatusId = data.monitorStatusId;
|
|
106
|
+
row.startsAt = new Date("2026-08-01T00:00:00.000Z");
|
|
107
|
+
if (data.projectId) {
|
|
108
|
+
row.projectId = data.projectId;
|
|
109
|
+
}
|
|
110
|
+
if (data.endsAt) {
|
|
111
|
+
row.endsAt = data.endsAt;
|
|
112
|
+
}
|
|
113
|
+
return row;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function mockBridge(): jest.SpyInstance {
|
|
117
|
+
return jest
|
|
118
|
+
.spyOn(NetworkSiteService, "onMonitorStatusChanged")
|
|
119
|
+
.mockResolvedValue(undefined as never);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function mockMonitorStatusWrite(): jest.SpyInstance {
|
|
123
|
+
return jest.spyOn(MonitorService, "updateOneBy").mockResolvedValue(1);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Drives the hook exactly as DatabaseService.create does after the INSERT:
|
|
128
|
+
* with the saved row and the createBy that produced it. A first-status
|
|
129
|
+
* carryForward (no predecessor, no successor) keeps the predecessor
|
|
130
|
+
* bookkeeping out of the way - it is not what is under test here.
|
|
131
|
+
*/
|
|
132
|
+
async function runOnCreateSuccess(data: {
|
|
133
|
+
createdItem: MonitorStatusTimeline;
|
|
134
|
+
createByData?: MonitorStatusTimeline | undefined;
|
|
135
|
+
props?: DatabaseCommonInteractionProps | undefined;
|
|
136
|
+
}): Promise<MonitorStatusTimeline> {
|
|
137
|
+
const onCreate: OnCreate<MonitorStatusTimeline> = {
|
|
138
|
+
createBy: {
|
|
139
|
+
data: data.createByData || data.createdItem,
|
|
140
|
+
props: data.props || ROOT_PROPS,
|
|
141
|
+
},
|
|
142
|
+
carryForward: {
|
|
143
|
+
statusTimelineBeforeThisStatus: null,
|
|
144
|
+
statusTimelineAfterThisStatus: null,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return await (MonitorStatusTimelineService as any).onCreateSuccess(
|
|
149
|
+
onCreate,
|
|
150
|
+
data.createdItem,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* Drives create() exactly as the probe path does - root props, no tenantId -
|
|
156
|
+
* with super.create (DatabaseService.prototype.create: hooks, validation, the
|
|
157
|
+
* INSERT) stubbed to resolve the saved row, and the feed item (DB lookups +
|
|
158
|
+
* Slack/Teams HTTP) stubbed. What is left running is exactly what create()
|
|
159
|
+
* owns: lock -> super.create -> release -> bridge -> feed item.
|
|
160
|
+
*/
|
|
161
|
+
async function runCreate(data: {
|
|
162
|
+
createdItem: MonitorStatusTimeline;
|
|
163
|
+
createByData?: MonitorStatusTimeline | undefined;
|
|
164
|
+
props?: DatabaseCommonInteractionProps | undefined;
|
|
165
|
+
}): Promise<MonitorStatusTimeline> {
|
|
166
|
+
return await MonitorStatusTimelineService.create({
|
|
167
|
+
data: data.createByData || data.createdItem,
|
|
168
|
+
props: data.props || ROOT_PROPS,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function expectBridgedOnceWith(
|
|
173
|
+
bridgeSpy: jest.SpyInstance,
|
|
174
|
+
expected: { projectId: ObjectID; monitorStatusId: ObjectID },
|
|
175
|
+
): void {
|
|
176
|
+
expect(bridgeSpy).toHaveBeenCalledTimes(1);
|
|
177
|
+
|
|
178
|
+
const args: any = bridgeSpy.mock.calls[0]![0];
|
|
179
|
+
|
|
180
|
+
expect(args.projectId.toString()).toBe(expected.projectId.toString());
|
|
181
|
+
expect(
|
|
182
|
+
args.monitorIds.map((id: ObjectID) => {
|
|
183
|
+
return id.toString();
|
|
184
|
+
}),
|
|
185
|
+
).toEqual([MONITOR_ID.toString()]);
|
|
186
|
+
expect(args.monitorStatusId.toString()).toBe(
|
|
187
|
+
expected.monitorStatusId.toString(),
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
describe("MonitorStatusTimelineService.create - the probe path bridge", () => {
|
|
192
|
+
let superCreateSpy: jest.SpyInstance;
|
|
193
|
+
let feedItemSpy: jest.SpyInstance;
|
|
194
|
+
|
|
195
|
+
// a unique object standing in for the redis-semaphore mutex.
|
|
196
|
+
const fakeMutex: { id: string } = { id: "fake-mutex" };
|
|
197
|
+
|
|
198
|
+
beforeEach(() => {
|
|
199
|
+
lockMock.mockReset();
|
|
200
|
+
releaseMock.mockReset();
|
|
201
|
+
|
|
202
|
+
lockMock.mockResolvedValue(fakeMutex);
|
|
203
|
+
releaseMock.mockResolvedValue(undefined);
|
|
204
|
+
|
|
205
|
+
superCreateSpy = jest.spyOn(DatabaseService.prototype, "create");
|
|
206
|
+
|
|
207
|
+
feedItemSpy = jest
|
|
208
|
+
.spyOn(
|
|
209
|
+
MonitorStatusTimelineService as unknown as {
|
|
210
|
+
createStatusChangeFeedItem: () => Promise<void>;
|
|
211
|
+
},
|
|
212
|
+
"createStatusChangeFeedItem",
|
|
213
|
+
)
|
|
214
|
+
.mockResolvedValue(undefined);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
afterEach(() => {
|
|
218
|
+
jest.restoreAllMocks();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
/*
|
|
222
|
+
* super.create resolves the saved row. Its hooks (onBeforeCreate /
|
|
223
|
+
* onCreateSuccess) do not run here - they are DatabaseService.create's
|
|
224
|
+
* responsibility and are pinned separately below.
|
|
225
|
+
*/
|
|
226
|
+
function stubSuperCreate(createdItem: MonitorStatusTimeline): void {
|
|
227
|
+
superCreateSpy.mockResolvedValue(createdItem);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
it("bridges a new current row exactly once with root props and no tenantId", async () => {
|
|
231
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
232
|
+
|
|
233
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
234
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
235
|
+
projectId: PROJECT_ID,
|
|
236
|
+
});
|
|
237
|
+
stubSuperCreate(createdItem);
|
|
238
|
+
|
|
239
|
+
const result: MonitorStatusTimeline = await runCreate({
|
|
240
|
+
createdItem: createdItem,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
expect(result).toBe(createdItem);
|
|
244
|
+
|
|
245
|
+
/*
|
|
246
|
+
* The probe path's exact shape: root, no tenantId. The create went
|
|
247
|
+
* through the locked path (a monitorId is set), and the bridge fired
|
|
248
|
+
* off the row that was written - not off anything tenant-gated.
|
|
249
|
+
*/
|
|
250
|
+
const createArgs: any = superCreateSpy.mock.calls[0]![0];
|
|
251
|
+
expect(createArgs.props.isRoot).toBe(true);
|
|
252
|
+
expect(createArgs.props.tenantId).toBeUndefined();
|
|
253
|
+
expect(lockMock).toHaveBeenCalledTimes(1);
|
|
254
|
+
expect(releaseMock).toHaveBeenCalledTimes(1);
|
|
255
|
+
|
|
256
|
+
expectBridgedOnceWith(bridge, {
|
|
257
|
+
projectId: PROJECT_ID,
|
|
258
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it("bridges AFTER super.create has resolved and the mutex is released, and before the feed item", async () => {
|
|
263
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
264
|
+
|
|
265
|
+
stubSuperCreate(
|
|
266
|
+
fakeTimelineRow({
|
|
267
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
268
|
+
projectId: PROJECT_ID,
|
|
269
|
+
}),
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
await runCreate({
|
|
273
|
+
createdItem: fakeTimelineRow({
|
|
274
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
275
|
+
projectId: PROJECT_ID,
|
|
276
|
+
}),
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
/*
|
|
280
|
+
* super.create -> release -> bridge -> feed item.
|
|
281
|
+
*
|
|
282
|
+
* After super.create: the timeline row and (in onCreateSuccess) the
|
|
283
|
+
* monitor's currentMonitorStatusId are written, and
|
|
284
|
+
* NetworkDeviceService.refreshStampedMonitorStatus (and anything else
|
|
285
|
+
* the rollup reads) derives from Monitor.currentMonitorStatusId, so the
|
|
286
|
+
* bridge must observe the new value, not the old one.
|
|
287
|
+
*
|
|
288
|
+
* After release: the bridge stamps every bound device and recomputes
|
|
289
|
+
* each site chain (alerts, workspace notifications). Under the lock,
|
|
290
|
+
* one slow rollup would make a concurrent status write for the same
|
|
291
|
+
* monitor be REFUSED past the semaphore's acquire timeout.
|
|
292
|
+
*
|
|
293
|
+
* Before the feed item: a device stamp must not wait on Slack/Teams.
|
|
294
|
+
*/
|
|
295
|
+
expect(superCreateSpy.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
296
|
+
releaseMock.mock.invocationCallOrder[0]!,
|
|
297
|
+
);
|
|
298
|
+
expect(releaseMock.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
299
|
+
bridge.mock.invocationCallOrder[0]!,
|
|
300
|
+
);
|
|
301
|
+
expect(bridge.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
302
|
+
feedItemSpy.mock.invocationCallOrder[0]!,
|
|
303
|
+
);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("does not bridge a row that is already closed (endsAt set)", async () => {
|
|
307
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
308
|
+
|
|
309
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
310
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
311
|
+
projectId: PROJECT_ID,
|
|
312
|
+
endsAt: new Date("2026-08-01T01:00:00.000Z"),
|
|
313
|
+
});
|
|
314
|
+
stubSuperCreate(createdItem);
|
|
315
|
+
|
|
316
|
+
await runCreate({ createdItem: createdItem });
|
|
317
|
+
|
|
318
|
+
// A closed row is history, not the current status: nothing moves.
|
|
319
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
320
|
+
// The lock was still taken and released around the write itself.
|
|
321
|
+
expect(releaseMock).toHaveBeenCalledTimes(1);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("does not bridge when super.create throws", async () => {
|
|
325
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
326
|
+
superCreateSpy.mockRejectedValue(new Error("insert failed"));
|
|
327
|
+
|
|
328
|
+
await expect(
|
|
329
|
+
runCreate({
|
|
330
|
+
createdItem: fakeTimelineRow({
|
|
331
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
332
|
+
projectId: PROJECT_ID,
|
|
333
|
+
}),
|
|
334
|
+
}),
|
|
335
|
+
).rejects.toThrow("insert failed");
|
|
336
|
+
|
|
337
|
+
// No row, no status change, nothing to stamp - but the lock is released.
|
|
338
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
339
|
+
expect(releaseMock).toHaveBeenCalledTimes(1);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it("falls back to the createBy data when the saved row carries no projectId", async () => {
|
|
343
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
344
|
+
|
|
345
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
346
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
347
|
+
projectId: undefined,
|
|
348
|
+
});
|
|
349
|
+
const createByData: MonitorStatusTimeline = fakeTimelineRow({
|
|
350
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
351
|
+
projectId: PROJECT_ID,
|
|
352
|
+
});
|
|
353
|
+
stubSuperCreate(createdItem);
|
|
354
|
+
|
|
355
|
+
await runCreate({
|
|
356
|
+
createdItem: createdItem,
|
|
357
|
+
createByData: createByData,
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
expectBridgedOnceWith(bridge, {
|
|
361
|
+
projectId: PROJECT_ID,
|
|
362
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it("falls back to props.tenantId when neither the row nor the data has a projectId", async () => {
|
|
367
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
368
|
+
|
|
369
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
370
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
371
|
+
projectId: undefined,
|
|
372
|
+
});
|
|
373
|
+
stubSuperCreate(createdItem);
|
|
374
|
+
|
|
375
|
+
await runCreate({
|
|
376
|
+
createdItem: createdItem,
|
|
377
|
+
props: {
|
|
378
|
+
isRoot: true,
|
|
379
|
+
tenantId: PROJECT_ID,
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
expectBridgedOnceWith(bridge, {
|
|
384
|
+
projectId: PROJECT_ID,
|
|
385
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it("skips the bridge, with a warning, when no projectId can be resolved at all", async () => {
|
|
390
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
391
|
+
const warn: jest.SpyInstance = jest
|
|
392
|
+
.spyOn(logger, "warn")
|
|
393
|
+
.mockImplementation(() => {
|
|
394
|
+
return undefined;
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
398
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
399
|
+
projectId: undefined,
|
|
400
|
+
});
|
|
401
|
+
stubSuperCreate(createdItem);
|
|
402
|
+
|
|
403
|
+
const result: MonitorStatusTimeline = await runCreate({
|
|
404
|
+
createdItem: createdItem,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
expect(result).toBe(createdItem);
|
|
408
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
409
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it("a bridge that throws does not fail the timeline create", async () => {
|
|
413
|
+
jest
|
|
414
|
+
.spyOn(NetworkSiteService, "onMonitorStatusChanged")
|
|
415
|
+
.mockRejectedValue(new Error("rollup exploded") as never);
|
|
416
|
+
const error: jest.SpyInstance = jest
|
|
417
|
+
.spyOn(logger, "error")
|
|
418
|
+
.mockImplementation(() => {
|
|
419
|
+
return undefined;
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
423
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
424
|
+
projectId: PROJECT_ID,
|
|
425
|
+
});
|
|
426
|
+
stubSuperCreate(createdItem);
|
|
427
|
+
|
|
428
|
+
/*
|
|
429
|
+
* The timeline row and the monitor's current status are already
|
|
430
|
+
* written by the time the bridge runs; a rollup failure surfacing here
|
|
431
|
+
* would turn a persisted status change into a failed probe ingest.
|
|
432
|
+
*/
|
|
433
|
+
await expect(runCreate({ createdItem: createdItem })).resolves.toBe(
|
|
434
|
+
createdItem,
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
expect(error).toHaveBeenCalledTimes(1);
|
|
438
|
+
expect(String(error.mock.calls[0]![0])).toContain("rollup exploded");
|
|
439
|
+
|
|
440
|
+
// The failed bridge did not stop the feed item either.
|
|
441
|
+
expect(feedItemSpy).toHaveBeenCalledTimes(1);
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
describe("MonitorStatusTimelineService.onCreateSuccess - writes the monitor, never bridges", () => {
|
|
446
|
+
afterEach(() => {
|
|
447
|
+
jest.restoreAllMocks();
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it("writes the monitor's current status with the caller's props and leaves the bridge to create()", async () => {
|
|
451
|
+
const monitorWrite: jest.SpyInstance = mockMonitorStatusWrite();
|
|
452
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
453
|
+
|
|
454
|
+
const createdItem: MonitorStatusTimeline = fakeTimelineRow({
|
|
455
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
456
|
+
projectId: PROJECT_ID,
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
await expect(
|
|
460
|
+
runOnCreateSuccess({ createdItem: createdItem }),
|
|
461
|
+
).resolves.toBe(createdItem);
|
|
462
|
+
|
|
463
|
+
/*
|
|
464
|
+
* The monitor's current status is written with the caller's props -
|
|
465
|
+
* root, no tenantId - which is precisely the write that never reaches
|
|
466
|
+
* MonitorService.onUpdateSuccess's tenant-gated changeMonitorStatus.
|
|
467
|
+
*/
|
|
468
|
+
expect(monitorWrite).toHaveBeenCalledTimes(1);
|
|
469
|
+
const writeArgs: any = monitorWrite.mock.calls[0]![0];
|
|
470
|
+
expect(writeArgs.data.currentMonitorStatusId.toString()).toBe(
|
|
471
|
+
OFFLINE_STATUS_ID.toString(),
|
|
472
|
+
);
|
|
473
|
+
expect(writeArgs.props.isRoot).toBe(true);
|
|
474
|
+
expect(writeArgs.props.tenantId).toBeUndefined();
|
|
475
|
+
|
|
476
|
+
/*
|
|
477
|
+
* This hook runs while create() still holds the per-monitor mutex, so
|
|
478
|
+
* the bridge (device stamps, site rollups, alerts, notifications) must
|
|
479
|
+
* NOT run from here: create() runs it right after the release. A bridge
|
|
480
|
+
* call from this hook would put it back under the lock.
|
|
481
|
+
*/
|
|
482
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("does not write the monitor for a row that is already closed (endsAt set)", async () => {
|
|
486
|
+
const monitorWrite: jest.SpyInstance = mockMonitorStatusWrite();
|
|
487
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
488
|
+
|
|
489
|
+
await runOnCreateSuccess({
|
|
490
|
+
createdItem: fakeTimelineRow({
|
|
491
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
492
|
+
projectId: PROJECT_ID,
|
|
493
|
+
endsAt: new Date("2026-08-01T01:00:00.000Z"),
|
|
494
|
+
}),
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// A closed row is history, not the current status: nothing moves.
|
|
498
|
+
expect(monitorWrite).not.toHaveBeenCalled();
|
|
499
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
describe("MonitorStatusTimelineService.onDeleteSuccess - bridging the surviving status", () => {
|
|
504
|
+
afterEach(() => {
|
|
505
|
+
jest.restoreAllMocks();
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
function runOnDeleteSuccess(
|
|
509
|
+
carryForward: ObjectID | null,
|
|
510
|
+
): Promise<OnDelete<MonitorStatusTimeline>> {
|
|
511
|
+
const onDelete: OnDelete<MonitorStatusTimeline> = {
|
|
512
|
+
deleteBy: {
|
|
513
|
+
query: {
|
|
514
|
+
_id: ROW_ID.toString(),
|
|
515
|
+
},
|
|
516
|
+
props: ROOT_PROPS,
|
|
517
|
+
} as DeleteBy<MonitorStatusTimeline>,
|
|
518
|
+
carryForward: carryForward,
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
return (MonitorStatusTimelineService as any).onDeleteSuccess(onDelete, [
|
|
522
|
+
ROW_ID,
|
|
523
|
+
]);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
it("bridges to the surviving latest status, selecting its projectId to do so", async () => {
|
|
527
|
+
const findLatest: jest.SpyInstance = jest
|
|
528
|
+
.spyOn(MonitorStatusTimelineService, "findOneBy")
|
|
529
|
+
.mockResolvedValue(
|
|
530
|
+
fakeTimelineRow({
|
|
531
|
+
monitorStatusId: OPERATIONAL_STATUS_ID,
|
|
532
|
+
projectId: PROJECT_ID,
|
|
533
|
+
}),
|
|
534
|
+
);
|
|
535
|
+
const monitorWrite: jest.SpyInstance = mockMonitorStatusWrite();
|
|
536
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
537
|
+
|
|
538
|
+
await runOnDeleteSuccess(MONITOR_ID);
|
|
539
|
+
|
|
540
|
+
// The projectId for the bridge comes off the row already being read.
|
|
541
|
+
expect(findLatest).toHaveBeenCalledTimes(1);
|
|
542
|
+
const findArgs: any = findLatest.mock.calls[0]![0];
|
|
543
|
+
expect(findArgs.select.projectId).toBe(true);
|
|
544
|
+
expect(findArgs.select.monitorStatusId).toBe(true);
|
|
545
|
+
|
|
546
|
+
expect(monitorWrite).toHaveBeenCalledTimes(1);
|
|
547
|
+
expect(
|
|
548
|
+
monitorWrite.mock.calls[0]![0].data.currentMonitorStatusId.toString(),
|
|
549
|
+
).toBe(OPERATIONAL_STATUS_ID.toString());
|
|
550
|
+
|
|
551
|
+
expectBridgedOnceWith(bridge, {
|
|
552
|
+
projectId: PROJECT_ID,
|
|
553
|
+
monitorStatusId: OPERATIONAL_STATUS_ID,
|
|
554
|
+
});
|
|
555
|
+
expect(monitorWrite.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
556
|
+
bridge.mock.invocationCallOrder[0]!,
|
|
557
|
+
);
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
it("does not bridge when no status survives for the monitor", async () => {
|
|
561
|
+
jest
|
|
562
|
+
.spyOn(MonitorStatusTimelineService, "findOneBy")
|
|
563
|
+
.mockResolvedValue(null);
|
|
564
|
+
const monitorWrite: jest.SpyInstance = mockMonitorStatusWrite();
|
|
565
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
566
|
+
|
|
567
|
+
await runOnDeleteSuccess(MONITOR_ID);
|
|
568
|
+
|
|
569
|
+
expect(monitorWrite).not.toHaveBeenCalled();
|
|
570
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
it("does nothing without a monitorId carryForward", async () => {
|
|
574
|
+
const findLatest: jest.SpyInstance = jest.spyOn(
|
|
575
|
+
MonitorStatusTimelineService,
|
|
576
|
+
"findOneBy",
|
|
577
|
+
);
|
|
578
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
579
|
+
|
|
580
|
+
await runOnDeleteSuccess(null);
|
|
581
|
+
|
|
582
|
+
expect(findLatest).not.toHaveBeenCalled();
|
|
583
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
it("a bridge that throws does not fail the delete", async () => {
|
|
587
|
+
jest.spyOn(MonitorStatusTimelineService, "findOneBy").mockResolvedValue(
|
|
588
|
+
fakeTimelineRow({
|
|
589
|
+
monitorStatusId: OPERATIONAL_STATUS_ID,
|
|
590
|
+
projectId: PROJECT_ID,
|
|
591
|
+
}),
|
|
592
|
+
);
|
|
593
|
+
mockMonitorStatusWrite();
|
|
594
|
+
jest
|
|
595
|
+
.spyOn(NetworkSiteService, "onMonitorStatusChanged")
|
|
596
|
+
.mockRejectedValue(new Error("rollup exploded") as never);
|
|
597
|
+
jest.spyOn(logger, "error").mockImplementation(() => {
|
|
598
|
+
return undefined;
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
await expect(runOnDeleteSuccess(MONITOR_ID)).resolves.toBeDefined();
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
describe("MonitorService.refreshMonitorCurrentStatus - bridging a repaired status", () => {
|
|
606
|
+
afterEach(() => {
|
|
607
|
+
jest.restoreAllMocks();
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
function fakeMonitor(currentMonitorStatusId: ObjectID | undefined): Monitor {
|
|
611
|
+
return {
|
|
612
|
+
id: MONITOR_ID,
|
|
613
|
+
_id: MONITOR_ID.toString(),
|
|
614
|
+
projectId: PROJECT_ID,
|
|
615
|
+
currentMonitorStatusId: currentMonitorStatusId,
|
|
616
|
+
} as unknown as Monitor;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
it("bridges when the current status id actually changed", async () => {
|
|
620
|
+
const findMonitor: jest.SpyInstance = jest
|
|
621
|
+
.spyOn(MonitorService, "findOneById")
|
|
622
|
+
.mockResolvedValue(fakeMonitor(OPERATIONAL_STATUS_ID));
|
|
623
|
+
jest.spyOn(MonitorStatusTimelineService, "findOneBy").mockResolvedValue(
|
|
624
|
+
fakeTimelineRow({
|
|
625
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
626
|
+
projectId: PROJECT_ID,
|
|
627
|
+
}),
|
|
628
|
+
);
|
|
629
|
+
const monitorWrite: jest.SpyInstance = jest
|
|
630
|
+
.spyOn(MonitorService, "updateOneById")
|
|
631
|
+
.mockResolvedValue(1);
|
|
632
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
633
|
+
|
|
634
|
+
await MonitorService.refreshMonitorCurrentStatus(MONITOR_ID);
|
|
635
|
+
|
|
636
|
+
// The monitor read has to carry projectId or there is nothing to bridge with.
|
|
637
|
+
expect(findMonitor.mock.calls[0]![0].select.projectId).toBe(true);
|
|
638
|
+
|
|
639
|
+
expect(monitorWrite).toHaveBeenCalledTimes(1);
|
|
640
|
+
expect(
|
|
641
|
+
monitorWrite.mock.calls[0]![0].data.currentMonitorStatusId.toString(),
|
|
642
|
+
).toBe(OFFLINE_STATUS_ID.toString());
|
|
643
|
+
|
|
644
|
+
expectBridgedOnceWith(bridge, {
|
|
645
|
+
projectId: PROJECT_ID,
|
|
646
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
647
|
+
});
|
|
648
|
+
expect(monitorWrite.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
649
|
+
bridge.mock.invocationCallOrder[0]!,
|
|
650
|
+
);
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
it("neither writes nor bridges when the id is already in sync", async () => {
|
|
654
|
+
jest
|
|
655
|
+
.spyOn(MonitorService, "findOneById")
|
|
656
|
+
.mockResolvedValue(fakeMonitor(OFFLINE_STATUS_ID));
|
|
657
|
+
jest.spyOn(MonitorStatusTimelineService, "findOneBy").mockResolvedValue(
|
|
658
|
+
fakeTimelineRow({
|
|
659
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
660
|
+
projectId: PROJECT_ID,
|
|
661
|
+
}),
|
|
662
|
+
);
|
|
663
|
+
const monitorWrite: jest.SpyInstance = jest.spyOn(
|
|
664
|
+
MonitorService,
|
|
665
|
+
"updateOneById",
|
|
666
|
+
);
|
|
667
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
668
|
+
|
|
669
|
+
await MonitorService.refreshMonitorCurrentStatus(MONITOR_ID);
|
|
670
|
+
|
|
671
|
+
/*
|
|
672
|
+
* An unchanged status must not churn every site rollup above the
|
|
673
|
+
* device on each repair pass.
|
|
674
|
+
*/
|
|
675
|
+
expect(monitorWrite).not.toHaveBeenCalled();
|
|
676
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
it("falls back to the timeline row's projectId when the monitor read has none", async () => {
|
|
680
|
+
jest.spyOn(MonitorService, "findOneById").mockResolvedValue({
|
|
681
|
+
id: MONITOR_ID,
|
|
682
|
+
_id: MONITOR_ID.toString(),
|
|
683
|
+
currentMonitorStatusId: OPERATIONAL_STATUS_ID,
|
|
684
|
+
} as unknown as Monitor);
|
|
685
|
+
jest.spyOn(MonitorStatusTimelineService, "findOneBy").mockResolvedValue(
|
|
686
|
+
fakeTimelineRow({
|
|
687
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
688
|
+
projectId: PROJECT_ID,
|
|
689
|
+
}),
|
|
690
|
+
);
|
|
691
|
+
jest.spyOn(MonitorService, "updateOneById").mockResolvedValue(1);
|
|
692
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
693
|
+
|
|
694
|
+
await MonitorService.refreshMonitorCurrentStatus(MONITOR_ID);
|
|
695
|
+
|
|
696
|
+
expectBridgedOnceWith(bridge, {
|
|
697
|
+
projectId: PROJECT_ID,
|
|
698
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
it("a bridge that throws does not fail the repair", async () => {
|
|
703
|
+
jest
|
|
704
|
+
.spyOn(MonitorService, "findOneById")
|
|
705
|
+
.mockResolvedValue(fakeMonitor(OPERATIONAL_STATUS_ID));
|
|
706
|
+
jest.spyOn(MonitorStatusTimelineService, "findOneBy").mockResolvedValue(
|
|
707
|
+
fakeTimelineRow({
|
|
708
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
709
|
+
projectId: PROJECT_ID,
|
|
710
|
+
}),
|
|
711
|
+
);
|
|
712
|
+
jest.spyOn(MonitorService, "updateOneById").mockResolvedValue(1);
|
|
713
|
+
jest
|
|
714
|
+
.spyOn(NetworkSiteService, "onMonitorStatusChanged")
|
|
715
|
+
.mockRejectedValue(new Error("rollup exploded") as never);
|
|
716
|
+
jest.spyOn(logger, "error").mockImplementation(() => {
|
|
717
|
+
return undefined;
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
await expect(
|
|
721
|
+
MonitorService.refreshMonitorCurrentStatus(MONITOR_ID),
|
|
722
|
+
).resolves.toBeUndefined();
|
|
723
|
+
});
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
describe("MonitorService.changeMonitorStatus - no longer bridges directly", () => {
|
|
727
|
+
afterEach(() => {
|
|
728
|
+
jest.restoreAllMocks();
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it("creates the timeline row and leaves the bridge to MonitorStatusTimelineService.create", async () => {
|
|
732
|
+
jest
|
|
733
|
+
.spyOn(MonitorStatusTimelineService, "findOneBy")
|
|
734
|
+
.mockResolvedValue(null);
|
|
735
|
+
/*
|
|
736
|
+
* The timeline create is stubbed, so MonitorStatusTimelineService.create
|
|
737
|
+
* (the one place the bridge now lives on the create path, after its
|
|
738
|
+
* mutex is released) does not run. If changeMonitorStatus still called
|
|
739
|
+
* the bridge itself, it would show up here.
|
|
740
|
+
*/
|
|
741
|
+
const createTimeline: jest.SpyInstance = jest
|
|
742
|
+
.spyOn(MonitorStatusTimelineService, "create")
|
|
743
|
+
.mockResolvedValue(
|
|
744
|
+
fakeTimelineRow({
|
|
745
|
+
monitorStatusId: OFFLINE_STATUS_ID,
|
|
746
|
+
projectId: PROJECT_ID,
|
|
747
|
+
}),
|
|
748
|
+
);
|
|
749
|
+
const bridge: jest.SpyInstance = mockBridge();
|
|
750
|
+
|
|
751
|
+
await MonitorService.changeMonitorStatus(
|
|
752
|
+
PROJECT_ID,
|
|
753
|
+
[MONITOR_ID],
|
|
754
|
+
OFFLINE_STATUS_ID,
|
|
755
|
+
false,
|
|
756
|
+
"manual change",
|
|
757
|
+
undefined,
|
|
758
|
+
ROOT_PROPS,
|
|
759
|
+
);
|
|
760
|
+
|
|
761
|
+
expect(createTimeline).toHaveBeenCalledTimes(1);
|
|
762
|
+
expect(
|
|
763
|
+
createTimeline.mock.calls[0]![0].data.monitorStatusId.toString(),
|
|
764
|
+
).toBe(OFFLINE_STATUS_ID.toString());
|
|
765
|
+
expect(bridge).not.toHaveBeenCalled();
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
it("the bridge call is gone from the changeMonitorStatus source", () => {
|
|
769
|
+
const source: string = fs.readFileSync(
|
|
770
|
+
path.join(__dirname, "../../../Server/Services/MonitorService.ts"),
|
|
771
|
+
"utf8",
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
const bodyStart: number = source.indexOf(
|
|
775
|
+
"public async changeMonitorStatus(",
|
|
776
|
+
);
|
|
777
|
+
const bodyEnd: number = source.indexOf(
|
|
778
|
+
"private async createStatusTimelineWithRetry(",
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
expect(bodyStart).toBeGreaterThan(-1);
|
|
782
|
+
expect(bodyEnd).toBeGreaterThan(bodyStart);
|
|
783
|
+
|
|
784
|
+
const changeMonitorStatusBody: string = source.slice(bodyStart, bodyEnd);
|
|
785
|
+
|
|
786
|
+
expect(changeMonitorStatusBody).not.toContain(
|
|
787
|
+
"NetworkSiteService.onMonitorStatusChanged",
|
|
788
|
+
);
|
|
789
|
+
|
|
790
|
+
/*
|
|
791
|
+
* The ONLY direct call left in MonitorService is the one in
|
|
792
|
+
* refreshMonitorCurrentStatus, whose updateOneById does not go through
|
|
793
|
+
* a timeline create and so cannot be bridged from
|
|
794
|
+
* MonitorStatusTimelineService.create.
|
|
795
|
+
*/
|
|
796
|
+
const callSites: number = source.split(
|
|
797
|
+
"NetworkSiteService.onMonitorStatusChanged(",
|
|
798
|
+
).length;
|
|
799
|
+
|
|
800
|
+
expect(callSites - 1).toBe(1);
|
|
801
|
+
});
|
|
802
|
+
});
|