@oneuptime/common 11.5.8 → 11.5.10
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/Index.ts +13 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +178 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +179 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +179 -0
- package/Models/AnalyticsModels/NetworkFlow.ts +397 -0
- package/Models/DatabaseModels/AIAgentTaskPullRequest.ts +15 -6
- package/Models/DatabaseModels/AIRun.ts +37 -0
- package/Models/DatabaseModels/AIRunEvent.ts +34 -1
- package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +18 -0
- package/Models/DatabaseModels/GlobalConfig.ts +36 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/MarketingConversion.ts +198 -0
- package/Models/DatabaseModels/MetricSavedView.ts +34 -0
- package/Models/DatabaseModels/MetricType.ts +74 -0
- package/Models/DatabaseModels/NetworkDevice.ts +332 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +328 -0
- package/Models/DatabaseModels/NetworkInterface.ts +58 -0
- package/Models/DatabaseModels/Project.ts +62 -0
- package/Models/DatabaseModels/StatusPage.ts +42 -0
- package/Models/DatabaseModels/User.ts +37 -0
- package/Server/API/AIAgentTaskAPI.ts +38 -12
- package/Server/API/AIAgentTaskLogAPI.ts +49 -0
- package/Server/API/AIChatAPI.ts +16 -0
- package/Server/API/AIReadinessAPI.ts +84 -0
- package/Server/API/BaseAnalyticsAPI.ts +23 -0
- package/Server/API/CodeFixRunAPI.ts +182 -0
- package/Server/API/EnterpriseLicenseAPI.ts +14 -0
- package/Server/API/TelemetryExceptionAPI.ts +6 -1
- package/Server/EnvironmentConfig.ts +84 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.ts +95 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.ts +108 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Services/AIRunEventService.ts +15 -1
- package/Server/Services/AIRunService.ts +38 -1
- package/Server/Services/AnalyticsDatabaseService.ts +70 -1
- package/Server/Services/IncidentService.ts +13 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/LlmProviderService.ts +2 -0
- package/Server/Services/MarketingConversionService.ts +10 -0
- package/Server/Services/MetricItemAggMV1mByContainerService.ts +31 -0
- package/Server/Services/MetricItemAggMV1mByK8sClusterService.ts +31 -0
- package/Server/Services/MetricItemAggMV1mByServiceService.ts +31 -0
- package/Server/Services/MetricService.ts +970 -122
- package/Server/Services/MonitorService.ts +14 -0
- package/Server/Services/NetworkDeviceOwnerTeamService.ts +42 -0
- package/Server/Services/NetworkDeviceOwnerUserService.ts +106 -0
- package/Server/Services/NetworkFlowService.ts +11 -0
- package/Server/Services/OnCallDutyPolicyService.ts +11 -1
- package/Server/Services/ProjectService.ts +178 -0
- package/Server/Services/SpanService.ts +13 -9
- package/Server/Services/StatusPageService.ts +97 -0
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TelemetryExceptionService.ts +19 -90
- package/Server/Services/UserService.ts +59 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +37 -7
- package/Server/Types/Markdown.ts +9 -9
- package/Server/Types/MarkdownSlugify.ts +47 -0
- package/Server/Utils/AI/AIRunTranscript.ts +240 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +9 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +119 -5
- package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +75 -0
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +235 -0
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +2 -3
- package/Server/Utils/AI/Toolbox/CodeTools.ts +883 -0
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +519 -0
- package/Server/Utils/AI/Toolbox/Index.ts +27 -0
- package/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.ts +279 -0
- package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +19 -1
- package/Server/Utils/Attribution.ts +99 -0
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +600 -0
- package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +7 -2
- package/Server/Utils/LLM/LLMService.ts +397 -18
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +103 -0
- package/Server/Utils/Marketing/ConversionUploadProviders.ts +22 -0
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +270 -0
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +147 -0
- package/Server/Utils/Marketing/Providers/Meta.ts +148 -0
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +196 -0
- package/Server/Utils/Marketing/Providers/Reddit.ts +178 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +71 -7
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +31 -19
- package/Server/Utils/Monitor/MonitorIncident.ts +71 -7
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +57 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +94 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +19 -11
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +125 -14
- package/Server/Utils/ProductAnalytics.ts +133 -0
- package/Server/Utils/Telemetry/Telemetry.ts +39 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +21 -0
- package/Tests/Models/StatusPageEnableMcpServer.test.ts +125 -0
- package/Tests/Server/API/BaseAnalyticsAPI.test.ts +72 -0
- package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +9 -1
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +21 -2
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +173 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +1391 -0
- package/Tests/Server/Services/NetworkDeviceOwnerServices.test.ts +260 -0
- package/Tests/Server/Services/StatusPageServiceMcp.test.ts +223 -0
- package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +26 -3
- package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +12 -0
- package/Tests/Server/Types/Markdown.test.ts +106 -0
- package/Tests/Server/Utils/AI/AIRunTranscript.test.ts +182 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +411 -0
- package/Tests/Server/Utils/AI/CodeTools.test.ts +596 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +475 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +548 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +142 -0
- package/Tests/Server/Utils/AI/ScheduledMaintenanceTools.test.ts +176 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +63 -0
- package/Tests/Server/Utils/GitHubGetFileContent.test.ts +197 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilNetworkDevice.test.ts +389 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +502 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +764 -0
- package/Tests/Types/AI/AIAgentTaskStatus.test.ts +7 -6
- package/Tests/Types/AI/AIChatPageContext.test.ts +0 -0
- package/Tests/Types/AI/AIRunStatus.test.ts +42 -0
- package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +111 -2
- package/Tests/Types/Database/EndsWith.test.ts +64 -0
- package/Tests/Types/Database/GreaterThan.test.ts +62 -0
- package/Tests/Types/Database/GreaterThanOrEqual.test.ts +65 -0
- package/Tests/Types/Database/GreaterThanOrNull.test.ts +63 -0
- package/Tests/Types/Database/Includes.test.ts +65 -0
- package/Tests/Types/Database/IncludesAll.test.ts +65 -0
- package/Tests/Types/Database/IncludesNone.test.ts +65 -0
- package/Tests/Types/Database/IsNull.test.ts +44 -0
- package/Tests/Types/Database/LessThan.test.ts +62 -0
- package/Tests/Types/Database/LessThanOrEqual.test.ts +62 -0
- package/Tests/Types/Database/LessThanOrNull.test.ts +62 -0
- package/Tests/Types/Database/MultiSearch.test.ts +81 -0
- package/Tests/Types/Database/NotContains.test.ts +64 -0
- package/Tests/Types/Database/NotNull.test.ts +44 -0
- package/Tests/Types/Database/StartsWith.test.ts +64 -0
- package/Tests/Types/Log/LogSeverity.test.ts +78 -0
- package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +83 -1
- package/Tests/Types/Monitor/SnmpV3EnumParsing.test.ts +247 -0
- package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +263 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +167 -0
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +66 -0
- package/Tests/UI/Components/XAxis.test.ts +5 -3
- package/Tests/UI/Utils/AIChatExport/ChatWidgetData.test.ts +319 -0
- package/Tests/UI/Utils/AIChatExport/ChatWidgetMarkdown.test.ts +188 -0
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +76 -0
- package/Tests/Utils/Metrics/MetricExplorerUrl.test.ts +622 -0
- package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +474 -0
- package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +52 -4
- package/Types/AI/AIAgentTaskStatus.ts +13 -0
- package/Types/AI/AIChatPageContext.ts +137 -0
- package/Types/AI/AIChatTypes.ts +44 -0
- package/Types/AI/AIFixReadiness.ts +46 -0
- package/Types/AI/AIRunStatus.ts +11 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +11 -0
- package/Types/BaseDatabase/AggregateBy.ts +31 -2
- package/Types/BaseDatabase/AggregatedResult.ts +22 -0
- package/Types/BaseDatabase/AggregationInterval.ts +11 -0
- package/Types/BaseDatabase/AggregationIntervalUtil.ts +30 -5
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +16 -0
- package/Types/Email/EmailTemplateType.ts +3 -0
- package/Types/Log/LogSeverity.ts +61 -0
- package/Types/Marketing/MarketingConversion.ts +11 -0
- package/Types/Metrics/MetricQueryConfigData.ts +21 -0
- package/Types/Metrics/MetricQueryData.ts +8 -0
- package/Types/Metrics/MetricViewData.ts +8 -0
- package/Types/Monitor/MonitorMetricType.ts +8 -0
- package/Types/Monitor/MonitorStep.ts +9 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +12 -0
- package/Types/Monitor/MonitorType.ts +2 -1
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +17 -12
- package/Types/Monitor/SnmpMonitor/CdpNeighbor.ts +13 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +37 -3
- package/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.ts +46 -0
- package/Types/Monitor/SnmpMonitor/SnmpEntityInfo.ts +15 -0
- package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +8 -0
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +17 -8
- package/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.ts +53 -0
- package/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.ts +43 -0
- package/Types/Monitor/SnmpMonitor/SnmpSystemInfo.ts +16 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +119 -3
- package/Types/Monitor/SnmpMonitor/SnmpVersion.ts +40 -0
- package/Types/NetFlow/NetworkFlowRecord.ts +25 -0
- package/Types/Syslog/SyslogMessage.ts +18 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -0
- package/Types/Telemetry/TelemetrySavedViewType.ts +12 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +51 -0
- package/UI/Components/Charts/Bar/BarChart.tsx +51 -1
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +97 -26
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +336 -3
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +118 -1
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +336 -3
- package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +7 -0
- package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +15 -0
- package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +13 -0
- package/UI/Components/Charts/Line/LineChart.tsx +51 -0
- package/UI/Components/Charts/Types/ReferenceRegionProps.ts +12 -0
- package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +12 -0
- package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +1 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +0 -0
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +169 -0
- package/UI/Components/Charts/Utils/XAxis.ts +28 -4
- package/UI/Components/Forms/BasicForm.tsx +26 -8
- package/UI/Components/Icon/Icon.tsx +33 -13
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +9 -0
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +67 -0
- package/UI/Components/Page/ModelPage.tsx +6 -1
- package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +33 -4
- package/UI/Styles/Theme.css +1324 -0
- package/UI/Utils/AIChatExport/ChatWidgetData.ts +316 -0
- package/UI/Utils/AIChatExport/ChatWidgetMarkdown.ts +349 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +177 -0
- package/UI/Utils/AIChatExport/MarkdownBlocks.ts +327 -0
- package/UI/Utils/AIChatExport/MarkdownSafety.ts +215 -0
- package/UI/Utils/DownloadFile.ts +54 -0
- package/UI/Utils/User.ts +41 -2
- package/Utils/Analytics.ts +8 -6
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +74 -0
- package/Utils/Metrics/MetricExplorerUrl.ts +771 -0
- package/Utils/Metrics/MetricFormulaEvaluator.ts +410 -46
- package/Utils/Monitor/NetworkTopologyUtil.ts +261 -49
- package/Utils/ValueFormatter.ts +22 -1
- package/build/dist/Models/AnalyticsModels/Index.js +13 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +159 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +158 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +160 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +351 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +15 -7
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIRun.js +38 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIRunEvent.js +31 -0
- package/build/dist/Models/DatabaseModels/AIRunEvent.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +19 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +38 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +219 -0
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MetricSavedView.js +35 -0
- package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MetricType.js +76 -0
- package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +341 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +341 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +60 -0
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +65 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +43 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +38 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskAPI.js +37 -11
- package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskLogAPI.js +32 -7
- package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -0
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIReadinessAPI.js +57 -0
- package/build/dist/Server/API/AIReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/BaseAnalyticsAPI.js +19 -0
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CodeFixRunAPI.js +142 -0
- package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +8 -0
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryExceptionAPI.js +4 -0
- package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +51 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.js +80 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.js +37 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js +27 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js +47 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIRunEventService.js +8 -0
- package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +29 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +58 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +12 -0
- package/build/dist/Server/Services/IncidentService.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/LlmProviderService.js +2 -0
- package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
- package/build/dist/Server/Services/MarketingConversionService.js +9 -0
- package/build/dist/Server/Services/MarketingConversionService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +761 -125
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +18 -5
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +44 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +88 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/NetworkFlowService.js +9 -0
- package/build/dist/Server/Services/NetworkFlowService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyService.js +15 -6
- package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +146 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +8 -6
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +91 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +11 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryExceptionService.js +14 -61
- package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +52 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +33 -7
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +8 -8
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Types/MarkdownSlugify.js +47 -0
- package/build/dist/Server/Types/MarkdownSlugify.js.map +1 -0
- package/build/dist/Server/Utils/AI/AIRunTranscript.js +180 -0
- package/build/dist/Server/Utils/AI/AIRunTranscript.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +103 -5
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +55 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +211 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +654 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +389 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +19 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.js +239 -0
- package/build/dist/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +19 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -1
- package/build/dist/Server/Utils/Attribution.js +74 -0
- package/build/dist/Server/Utils/Attribution.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +439 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +1 -1
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +275 -19
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +40 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +20 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +177 -0
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +113 -0
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +109 -0
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +130 -0
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +126 -0
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +53 -9
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -10
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +54 -11
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +43 -3
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +68 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +17 -11
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +100 -15
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/ProductAnalytics.js +111 -0
- package/build/dist/Server/Utils/ProductAnalytics.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +32 -5
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Types/AI/AIAgentTaskStatus.js +12 -0
- package/build/dist/Types/AI/AIAgentTaskStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatPageContext.js +101 -0
- package/build/dist/Types/AI/AIChatPageContext.js.map +1 -0
- package/build/dist/Types/AI/AIChatTypes.js +2 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/AI/AIFixReadiness.js +9 -0
- package/build/dist/Types/AI/AIFixReadiness.js.map +1 -0
- package/build/dist/Types/AI/AIRunStatus.js +11 -0
- package/build/dist/Types/AI/AIRunStatus.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +11 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationInterval.js +11 -0
- package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +33 -5
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +2 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Log/LogSeverity.js +56 -0
- package/build/dist/Types/Log/LogSeverity.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +13 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +3 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +2 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js +41 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js +48 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js +38 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +96 -3
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVersion.js +38 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVersion.js.map +1 -1
- package/build/dist/Types/NetFlow/NetworkFlowRecord.js +2 -0
- package/build/dist/Types/NetFlow/NetworkFlowRecord.js.map +1 -0
- package/build/dist/Types/Syslog/SyslogMessage.js +2 -0
- package/build/dist/Types/Syslog/SyslogMessage.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetrySavedViewState.js +0 -7
- package/build/dist/Types/Telemetry/TelemetrySavedViewState.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetrySavedViewType.js +13 -0
- package/build/dist/Types/Telemetry/TelemetrySavedViewType.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +25 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +26 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +36 -12
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +217 -8
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +55 -4
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +217 -8
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +6 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js +2 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js +2 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +25 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js.map +1 -0
- package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js.map +1 -0
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +1 -0
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +0 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +121 -0
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +27 -4
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +24 -6
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +15 -8
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +58 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +7 -1
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +10 -4
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetData.js +217 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetData.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetMarkdown.js +234 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetMarkdown.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +111 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownBlocks.js +233 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownBlocks.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownSafety.js +134 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownSafety.js.map +1 -0
- package/build/dist/UI/Utils/DownloadFile.js +41 -0
- package/build/dist/UI/Utils/DownloadFile.js.map +1 -0
- package/build/dist/UI/Utils/User.js +35 -2
- package/build/dist/UI/Utils/User.js.map +1 -1
- package/build/dist/Utils/Analytics.js +8 -5
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +57 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/Metrics/MetricExplorerUrl.js +418 -0
- package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +296 -37
- package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +176 -40
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/ValueFormatter.js +20 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from "@jest/globals";
|
|
2
|
+
import NetworkDeviceOwnerUserService, {
|
|
3
|
+
NetworkDeviceOwners,
|
|
4
|
+
} from "../../../Server/Services/NetworkDeviceOwnerUserService";
|
|
5
|
+
import NetworkDeviceOwnerTeamService from "../../../Server/Services/NetworkDeviceOwnerTeamService";
|
|
6
|
+
import NetworkDeviceOwnerUser from "../../../Models/DatabaseModels/NetworkDeviceOwnerUser";
|
|
7
|
+
import NetworkDeviceOwnerTeam from "../../../Models/DatabaseModels/NetworkDeviceOwnerTeam";
|
|
8
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
9
|
+
import MonitorStep from "../../../Types/Monitor/MonitorStep";
|
|
10
|
+
import MonitorSteps from "../../../Types/Monitor/MonitorSteps";
|
|
11
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* getDeviceOwnersForMonitor fans a NetworkDevice's owner users/teams into
|
|
15
|
+
* monitor-created incidents/alerts and the owner-added notification job. The
|
|
16
|
+
* device id lives buried in monitor step config, so these tests pin the step
|
|
17
|
+
* selection rules (prefer the step that produced the probe response, fall
|
|
18
|
+
* back to the first device-referencing step), the no-device fast path that
|
|
19
|
+
* must not touch the database, and the shape/filtering of the returned id
|
|
20
|
+
* arrays. Database access is mocked at the findBy level.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const DEVICE_A: string = "8f2c1f0e-0000-4000-8000-0000000000aa";
|
|
24
|
+
const DEVICE_B: string = "8f2c1f0e-0000-4000-8000-0000000000bb";
|
|
25
|
+
|
|
26
|
+
function buildStep(networkDeviceId?: string): MonitorStep {
|
|
27
|
+
const step: MonitorStep = new MonitorStep();
|
|
28
|
+
|
|
29
|
+
if (networkDeviceId) {
|
|
30
|
+
step.data = {
|
|
31
|
+
...step.data,
|
|
32
|
+
networkDeviceMonitor: {
|
|
33
|
+
networkDeviceId: networkDeviceId,
|
|
34
|
+
},
|
|
35
|
+
} as MonitorStep["data"];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return step;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildMonitor(steps: Array<MonitorStep>): Monitor {
|
|
42
|
+
const monitorSteps: MonitorSteps = new MonitorSteps();
|
|
43
|
+
monitorSteps.data = {
|
|
44
|
+
monitorStepsInstanceArray: steps,
|
|
45
|
+
defaultMonitorStatusId: undefined,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const monitor: Monitor = new Monitor();
|
|
49
|
+
monitor.monitorSteps = monitorSteps;
|
|
50
|
+
|
|
51
|
+
return monitor;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function ownerUserRow(userId?: ObjectID): NetworkDeviceOwnerUser {
|
|
55
|
+
const row: NetworkDeviceOwnerUser = new NetworkDeviceOwnerUser();
|
|
56
|
+
if (userId) {
|
|
57
|
+
row.userId = userId;
|
|
58
|
+
}
|
|
59
|
+
return row;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function ownerTeamRow(teamId?: ObjectID): NetworkDeviceOwnerTeam {
|
|
63
|
+
const row: NetworkDeviceOwnerTeam = new NetworkDeviceOwnerTeam();
|
|
64
|
+
if (teamId) {
|
|
65
|
+
row.teamId = teamId;
|
|
66
|
+
}
|
|
67
|
+
return row;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function mockOwnerRows(options?: {
|
|
71
|
+
users?: Array<NetworkDeviceOwnerUser> | undefined;
|
|
72
|
+
teams?: Array<NetworkDeviceOwnerTeam> | undefined;
|
|
73
|
+
}): {
|
|
74
|
+
userFindBy: jest.SpyInstance;
|
|
75
|
+
teamFindBy: jest.SpyInstance;
|
|
76
|
+
} {
|
|
77
|
+
const userFindBy: jest.SpyInstance = jest
|
|
78
|
+
.spyOn(NetworkDeviceOwnerUserService, "findBy")
|
|
79
|
+
.mockResolvedValue(options?.users || []);
|
|
80
|
+
const teamFindBy: jest.SpyInstance = jest
|
|
81
|
+
.spyOn(NetworkDeviceOwnerTeamService, "findBy")
|
|
82
|
+
.mockResolvedValue(options?.teams || []);
|
|
83
|
+
|
|
84
|
+
return { userFindBy: userFindBy, teamFindBy: teamFindBy };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function queriedDeviceId(spy: jest.SpyInstance): string | undefined {
|
|
88
|
+
return spy.mock.calls[0]?.[0]?.query?.networkDeviceId?.toString();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
afterEach(() => {
|
|
92
|
+
jest.restoreAllMocks();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor — no-device fast path", () => {
|
|
96
|
+
test("a monitor with no steps returns empty owners without touching the database", async () => {
|
|
97
|
+
const { userFindBy, teamFindBy } = mockOwnerRows();
|
|
98
|
+
|
|
99
|
+
const owners: NetworkDeviceOwners =
|
|
100
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
101
|
+
monitor: buildMonitor([]),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(owners).toEqual({ ownerUserIds: [], ownerTeamIds: [] });
|
|
105
|
+
expect(userFindBy).not.toHaveBeenCalled();
|
|
106
|
+
expect(teamFindBy).not.toHaveBeenCalled();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("a monitor with no monitorSteps object at all behaves the same", async () => {
|
|
110
|
+
const { userFindBy, teamFindBy } = mockOwnerRows();
|
|
111
|
+
|
|
112
|
+
const owners: NetworkDeviceOwners =
|
|
113
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
114
|
+
monitor: new Monitor(),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(owners).toEqual({ ownerUserIds: [], ownerTeamIds: [] });
|
|
118
|
+
expect(userFindBy).not.toHaveBeenCalled();
|
|
119
|
+
expect(teamFindBy).not.toHaveBeenCalled();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("steps that reference no device return empty owners without queries", async () => {
|
|
123
|
+
const { userFindBy, teamFindBy } = mockOwnerRows();
|
|
124
|
+
|
|
125
|
+
const owners: NetworkDeviceOwners =
|
|
126
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
127
|
+
monitor: buildMonitor([buildStep(), buildStep()]),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(owners).toEqual({ ownerUserIds: [], ownerTeamIds: [] });
|
|
131
|
+
expect(userFindBy).not.toHaveBeenCalled();
|
|
132
|
+
expect(teamFindBy).not.toHaveBeenCalled();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe("NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor — step selection", () => {
|
|
137
|
+
test("the step that produced the probe response is preferred", async () => {
|
|
138
|
+
const stepA: MonitorStep = buildStep(DEVICE_A);
|
|
139
|
+
const stepB: MonitorStep = buildStep(DEVICE_B);
|
|
140
|
+
const { userFindBy, teamFindBy } = mockOwnerRows();
|
|
141
|
+
|
|
142
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
143
|
+
monitor: buildMonitor([stepA, stepB]),
|
|
144
|
+
monitorStepId: stepB.id.toString(),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
expect(queriedDeviceId(userFindBy)).toBe(DEVICE_B);
|
|
148
|
+
expect(queriedDeviceId(teamFindBy)).toBe(DEVICE_B);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("a monitorStepId matching no step falls back to the first device-referencing step", async () => {
|
|
152
|
+
const stepA: MonitorStep = buildStep(DEVICE_A);
|
|
153
|
+
const stepB: MonitorStep = buildStep(DEVICE_B);
|
|
154
|
+
const { userFindBy } = mockOwnerRows();
|
|
155
|
+
|
|
156
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
157
|
+
monitor: buildMonitor([stepA, stepB]),
|
|
158
|
+
monitorStepId: ObjectID.generate().toString(),
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
expect(queriedDeviceId(userFindBy)).toBe(DEVICE_A);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test("a matching step without device config falls back to the device-referencing step", async () => {
|
|
165
|
+
const stepWithoutDevice: MonitorStep = buildStep();
|
|
166
|
+
const stepWithDevice: MonitorStep = buildStep(DEVICE_B);
|
|
167
|
+
const { userFindBy } = mockOwnerRows();
|
|
168
|
+
|
|
169
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
170
|
+
monitor: buildMonitor([stepWithoutDevice, stepWithDevice]),
|
|
171
|
+
monitorStepId: stepWithoutDevice.id.toString(),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(queriedDeviceId(userFindBy)).toBe(DEVICE_B);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("callers without a step id pick up owners from the first device-referencing step", async () => {
|
|
178
|
+
const stepWithoutDevice: MonitorStep = buildStep();
|
|
179
|
+
const stepWithDevice: MonitorStep = buildStep(DEVICE_A);
|
|
180
|
+
const { userFindBy } = mockOwnerRows();
|
|
181
|
+
|
|
182
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
183
|
+
monitor: buildMonitor([stepWithoutDevice, stepWithDevice]),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
expect(queriedDeviceId(userFindBy)).toBe(DEVICE_A);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe("NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor — returned owners", () => {
|
|
191
|
+
test("owner user and team ids come back from the mocked rows", async () => {
|
|
192
|
+
const userId1: ObjectID = ObjectID.generate();
|
|
193
|
+
const userId2: ObjectID = ObjectID.generate();
|
|
194
|
+
const teamId: ObjectID = ObjectID.generate();
|
|
195
|
+
|
|
196
|
+
mockOwnerRows({
|
|
197
|
+
users: [ownerUserRow(userId1), ownerUserRow(userId2)],
|
|
198
|
+
teams: [ownerTeamRow(teamId)],
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const owners: NetworkDeviceOwners =
|
|
202
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
203
|
+
monitor: buildMonitor([buildStep(DEVICE_A)]),
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(owners.ownerUserIds.map(String)).toEqual([
|
|
207
|
+
userId1.toString(),
|
|
208
|
+
userId2.toString(),
|
|
209
|
+
]);
|
|
210
|
+
expect(owners.ownerTeamIds.map(String)).toEqual([teamId.toString()]);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test("rows missing their user/team id are filtered out of the result", async () => {
|
|
214
|
+
const userId: ObjectID = ObjectID.generate();
|
|
215
|
+
const teamId: ObjectID = ObjectID.generate();
|
|
216
|
+
|
|
217
|
+
mockOwnerRows({
|
|
218
|
+
users: [ownerUserRow(), ownerUserRow(userId)],
|
|
219
|
+
teams: [ownerTeamRow(teamId), ownerTeamRow()],
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
const owners: NetworkDeviceOwners =
|
|
223
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
224
|
+
monitor: buildMonitor([buildStep(DEVICE_A)]),
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
expect(owners.ownerUserIds.map(String)).toEqual([userId.toString()]);
|
|
228
|
+
expect(owners.ownerTeamIds.map(String)).toEqual([teamId.toString()]);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test("a device with no owners at all yields empty arrays (not undefined)", async () => {
|
|
232
|
+
const { userFindBy, teamFindBy } = mockOwnerRows();
|
|
233
|
+
|
|
234
|
+
const owners: NetworkDeviceOwners =
|
|
235
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
236
|
+
monitor: buildMonitor([buildStep(DEVICE_A)]),
|
|
237
|
+
monitorStepId: undefined,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
expect(owners.ownerUserIds).toEqual([]);
|
|
241
|
+
expect(owners.ownerTeamIds).toEqual([]);
|
|
242
|
+
// The device IS referenced, so both ownership tables are consulted once.
|
|
243
|
+
expect(userFindBy).toHaveBeenCalledTimes(1);
|
|
244
|
+
expect(teamFindBy).toHaveBeenCalledTimes(1);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("both queries are scoped to the referenced device id", async () => {
|
|
248
|
+
const { userFindBy, teamFindBy } = mockOwnerRows();
|
|
249
|
+
|
|
250
|
+
await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
|
|
251
|
+
monitor: buildMonitor([buildStep(DEVICE_A)]),
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
expect(queriedDeviceId(userFindBy)).toBe(DEVICE_A);
|
|
255
|
+
expect(queriedDeviceId(teamFindBy)).toBe(DEVICE_A);
|
|
256
|
+
expect(
|
|
257
|
+
userFindBy.mock.calls[0]?.[0]?.query?.networkDeviceId,
|
|
258
|
+
).toBeInstanceOf(ObjectID);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatusPageService MCP gate tests.
|
|
3
|
+
*
|
|
4
|
+
* resolveStatusPageIdOrNull and isMcpServerEnabled back the unauthenticated
|
|
5
|
+
* public status page MCP tools, so their contract is security-relevant:
|
|
6
|
+
* - a status page that does not exist and one that has MCP turned off must be
|
|
7
|
+
* indistinguishable to the caller (otherwise the tools become a status page
|
|
8
|
+
* enumeration oracle)
|
|
9
|
+
* - a database failure must propagate rather than collapse into "disabled", so
|
|
10
|
+
* an outage is reported as an error instead of being silently reported as an
|
|
11
|
+
* owner's privacy choice
|
|
12
|
+
*
|
|
13
|
+
* Both services' findOneBy are spied on, so no database is touched.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import StatusPageService from "../../../Server/Services/StatusPageService";
|
|
17
|
+
import StatusPageDomainService from "../../../Server/Services/StatusPageDomainService";
|
|
18
|
+
import StatusPage from "../../../Models/DatabaseModels/StatusPage";
|
|
19
|
+
import StatusPageDomain from "../../../Models/DatabaseModels/StatusPageDomain";
|
|
20
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
21
|
+
import { afterEach, describe, expect, test, jest } from "@jest/globals";
|
|
22
|
+
|
|
23
|
+
const VALID_UUID: string = "550e8400-e29b-41d4-a716-446655440000";
|
|
24
|
+
const DOMAIN: string = "status.company.com";
|
|
25
|
+
|
|
26
|
+
function statusPageDomainWith(statusPageId: ObjectID | null): StatusPageDomain {
|
|
27
|
+
return {
|
|
28
|
+
statusPageId: statusPageId ?? undefined,
|
|
29
|
+
} as unknown as StatusPageDomain;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function statusPageRow(): StatusPage {
|
|
33
|
+
return { _id: VALID_UUID } as unknown as StatusPage;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function spyOnStatusPageFindOneBy(): jest.SpyInstance {
|
|
37
|
+
return jest.spyOn(
|
|
38
|
+
StatusPageService,
|
|
39
|
+
"findOneBy",
|
|
40
|
+
) as unknown as jest.SpyInstance;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function spyOnDomainFindOneBy(): jest.SpyInstance {
|
|
44
|
+
return jest.spyOn(
|
|
45
|
+
StatusPageDomainService,
|
|
46
|
+
"findOneBy",
|
|
47
|
+
) as unknown as jest.SpyInstance;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe("StatusPageService MCP gate", () => {
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
jest.restoreAllMocks();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe("resolveStatusPageIdOrNull", () => {
|
|
56
|
+
test("resolves a UUID without querying the domain table", async () => {
|
|
57
|
+
const domainSpy: jest.SpyInstance = spyOnDomainFindOneBy();
|
|
58
|
+
|
|
59
|
+
const result: ObjectID | null =
|
|
60
|
+
await StatusPageService.resolveStatusPageIdOrNull(VALID_UUID);
|
|
61
|
+
|
|
62
|
+
expect(result?.toString()).toBe(VALID_UUID);
|
|
63
|
+
expect(domainSpy).not.toHaveBeenCalled();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("looks a domain up by fullDomain, requiring a verified domain", async () => {
|
|
67
|
+
const statusPageId: ObjectID = new ObjectID(VALID_UUID);
|
|
68
|
+
const domainSpy: jest.SpyInstance =
|
|
69
|
+
spyOnDomainFindOneBy().mockResolvedValue(
|
|
70
|
+
statusPageDomainWith(statusPageId) as never,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const result: ObjectID | null =
|
|
74
|
+
await StatusPageService.resolveStatusPageIdOrNull(DOMAIN);
|
|
75
|
+
|
|
76
|
+
expect(result?.toString()).toBe(VALID_UUID);
|
|
77
|
+
|
|
78
|
+
const args: Record<string, any> = domainSpy.mock.calls[0]![0] as Record<
|
|
79
|
+
string,
|
|
80
|
+
any
|
|
81
|
+
>;
|
|
82
|
+
|
|
83
|
+
expect(args["query"]["fullDomain"]).toBe(DOMAIN);
|
|
84
|
+
expect(args["query"]["domain"]).toEqual({ isVerified: true });
|
|
85
|
+
expect(args["props"]["isRoot"]).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("returns null when the domain is not registered", async () => {
|
|
89
|
+
spyOnDomainFindOneBy().mockResolvedValue(null as never);
|
|
90
|
+
|
|
91
|
+
await expect(
|
|
92
|
+
StatusPageService.resolveStatusPageIdOrNull(DOMAIN),
|
|
93
|
+
).resolves.toBeNull();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("returns null when the domain row carries no status page", async () => {
|
|
97
|
+
spyOnDomainFindOneBy().mockResolvedValue(
|
|
98
|
+
statusPageDomainWith(null) as never,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
await expect(
|
|
102
|
+
StatusPageService.resolveStatusPageIdOrNull(DOMAIN),
|
|
103
|
+
).resolves.toBeNull();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("returns null for an empty identifier without querying", async () => {
|
|
107
|
+
const domainSpy: jest.SpyInstance = spyOnDomainFindOneBy();
|
|
108
|
+
|
|
109
|
+
await expect(
|
|
110
|
+
StatusPageService.resolveStatusPageIdOrNull(""),
|
|
111
|
+
).resolves.toBeNull();
|
|
112
|
+
expect(domainSpy).not.toHaveBeenCalled();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("returns null for a malformed UUID rather than throwing", async () => {
|
|
116
|
+
await expect(
|
|
117
|
+
StatusPageService.resolveStatusPageIdOrNull("not-a-uuid"),
|
|
118
|
+
).resolves.toBeNull();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("returns null for a dotless hostname", async () => {
|
|
122
|
+
/*
|
|
123
|
+
* The dot is the discriminator, mirroring resolveStatusPageIdOrThrow in
|
|
124
|
+
* StatusPageAPI. "localhost" therefore goes down the UUID path and fails
|
|
125
|
+
* there. Pinned so the two resolvers cannot silently diverge.
|
|
126
|
+
*/
|
|
127
|
+
await expect(
|
|
128
|
+
StatusPageService.resolveStatusPageIdOrNull("localhost"),
|
|
129
|
+
).resolves.toBeNull();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("isMcpServerEnabled", () => {
|
|
134
|
+
test("is true when a UUID matches a status page with MCP enabled", async () => {
|
|
135
|
+
spyOnStatusPageFindOneBy().mockResolvedValue(statusPageRow() as never);
|
|
136
|
+
|
|
137
|
+
await expect(
|
|
138
|
+
StatusPageService.isMcpServerEnabled(VALID_UUID),
|
|
139
|
+
).resolves.toBe(true);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("is false when the status page has MCP disabled", async () => {
|
|
143
|
+
/*
|
|
144
|
+
* The enableMcpServer predicate is in the query, so a gated page simply
|
|
145
|
+
* does not match.
|
|
146
|
+
*/
|
|
147
|
+
spyOnStatusPageFindOneBy().mockResolvedValue(null as never);
|
|
148
|
+
|
|
149
|
+
await expect(
|
|
150
|
+
StatusPageService.isMcpServerEnabled(VALID_UUID),
|
|
151
|
+
).resolves.toBe(false);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("folds the flag into the query and reads as root", async () => {
|
|
155
|
+
const spy: jest.SpyInstance =
|
|
156
|
+
spyOnStatusPageFindOneBy().mockResolvedValue(statusPageRow() as never);
|
|
157
|
+
|
|
158
|
+
await StatusPageService.isMcpServerEnabled(VALID_UUID);
|
|
159
|
+
|
|
160
|
+
const args: Record<string, any> = spy.mock.calls[0]![0] as Record<
|
|
161
|
+
string,
|
|
162
|
+
any
|
|
163
|
+
>;
|
|
164
|
+
|
|
165
|
+
expect(args["query"]["enableMcpServer"]).toBe(true);
|
|
166
|
+
expect(args["query"]["_id"].toString()).toBe(VALID_UUID);
|
|
167
|
+
expect(args["props"]["isRoot"]).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test("resolves a domain and then checks the flag", async () => {
|
|
171
|
+
spyOnDomainFindOneBy().mockResolvedValue(
|
|
172
|
+
statusPageDomainWith(new ObjectID(VALID_UUID)) as never,
|
|
173
|
+
);
|
|
174
|
+
const pageSpy: jest.SpyInstance =
|
|
175
|
+
spyOnStatusPageFindOneBy().mockResolvedValue(statusPageRow() as never);
|
|
176
|
+
|
|
177
|
+
await expect(StatusPageService.isMcpServerEnabled(DOMAIN)).resolves.toBe(
|
|
178
|
+
true,
|
|
179
|
+
);
|
|
180
|
+
expect(pageSpy).toHaveBeenCalledTimes(1);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("is false for an unknown status page, without a second query", async () => {
|
|
184
|
+
spyOnDomainFindOneBy().mockResolvedValue(null as never);
|
|
185
|
+
const pageSpy: jest.SpyInstance = spyOnStatusPageFindOneBy();
|
|
186
|
+
|
|
187
|
+
await expect(StatusPageService.isMcpServerEnabled(DOMAIN)).resolves.toBe(
|
|
188
|
+
false,
|
|
189
|
+
);
|
|
190
|
+
expect(pageSpy).not.toHaveBeenCalled();
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test("is false for an unresolvable identifier", async () => {
|
|
194
|
+
await expect(
|
|
195
|
+
StatusPageService.isMcpServerEnabled("not-a-uuid"),
|
|
196
|
+
).resolves.toBe(false);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("propagates a status page query failure instead of reporting disabled", async () => {
|
|
200
|
+
/*
|
|
201
|
+
* Fails closed either way, but the caller reports an error rather than
|
|
202
|
+
* telling the agent the owner turned MCP off.
|
|
203
|
+
*/
|
|
204
|
+
spyOnStatusPageFindOneBy().mockRejectedValue(
|
|
205
|
+
new Error("connection terminated") as never,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
await expect(
|
|
209
|
+
StatusPageService.isMcpServerEnabled(VALID_UUID),
|
|
210
|
+
).rejects.toThrow("connection terminated");
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test("propagates a domain query failure", async () => {
|
|
214
|
+
spyOnDomainFindOneBy().mockRejectedValue(
|
|
215
|
+
new Error("connection terminated") as never,
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
await expect(
|
|
219
|
+
StatusPageService.isMcpServerEnabled(DOMAIN),
|
|
220
|
+
).rejects.toThrow("connection terminated");
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import TelemetryExceptionService
|
|
1
|
+
import TelemetryExceptionService from "../../../Server/Services/TelemetryExceptionService";
|
|
2
|
+
import {
|
|
2
3
|
AIFixReadiness,
|
|
3
4
|
AIFixReadinessCheck,
|
|
4
|
-
} from "../../../
|
|
5
|
+
} from "../../../Types/AI/AIFixReadiness";
|
|
5
6
|
import FixRunBudget from "../../../Server/Utils/AI/CodeFix/FixRunBudget";
|
|
6
7
|
import LlmProviderService from "../../../Server/Services/LlmProviderService";
|
|
7
8
|
import ProjectService from "../../../Server/Services/ProjectService";
|
|
@@ -19,7 +20,8 @@ import AIAgent, {
|
|
|
19
20
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
20
21
|
import ObjectID from "../../../Types/ObjectID";
|
|
21
22
|
import OneUptimeDate from "../../../Types/Date";
|
|
22
|
-
import
|
|
23
|
+
import AIService from "../../../Server/Services/AIService";
|
|
24
|
+
import { describe, expect, test, afterEach, beforeEach } from "@jest/globals";
|
|
23
25
|
|
|
24
26
|
/*
|
|
25
27
|
* "Fix with AI Agent" readiness: every prerequisite is checked BEFORE a task
|
|
@@ -121,7 +123,24 @@ function getCheck(readiness: AIFixReadiness, id: string): AIFixReadinessCheck {
|
|
|
121
123
|
return check!;
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
/*
|
|
127
|
+
* The llmProvider check also gates on the daily autonomous token budget
|
|
128
|
+
* (AI_CODE_FIX_FEATURE is autonomous, so executeWithLogging enforces it).
|
|
129
|
+
* Default it to unset — these suites are about the other fail conditions.
|
|
130
|
+
*/
|
|
131
|
+
function mockBudgetNotExhausted(): void {
|
|
132
|
+
jest.spyOn(AIService, "getAutonomousDailyBudgetStatus").mockResolvedValue({
|
|
133
|
+
exhausted: false,
|
|
134
|
+
limitInTokens: null,
|
|
135
|
+
usedTokensToday: 0,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
124
139
|
describe("TelemetryExceptionService.getAIFixReadiness", () => {
|
|
140
|
+
beforeEach(() => {
|
|
141
|
+
mockBudgetNotExhausted();
|
|
142
|
+
});
|
|
143
|
+
|
|
125
144
|
afterEach(() => {
|
|
126
145
|
jest.restoreAllMocks();
|
|
127
146
|
});
|
|
@@ -237,6 +256,10 @@ describe("TelemetryExceptionService.getAIFixReadiness", () => {
|
|
|
237
256
|
* and free-global providers consume no balance and must never require one.
|
|
238
257
|
*/
|
|
239
258
|
describe("TelemetryExceptionService.getAIFixReadiness — AI balance gate", () => {
|
|
259
|
+
beforeEach(() => {
|
|
260
|
+
mockBudgetNotExhausted();
|
|
261
|
+
});
|
|
262
|
+
|
|
240
263
|
afterEach(() => {
|
|
241
264
|
jest.restoreAllMocks();
|
|
242
265
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import TelemetryExceptionService from "../../../Server/Services/TelemetryExceptionService";
|
|
2
|
+
import AIService from "../../../Server/Services/AIService";
|
|
2
3
|
import FixRunBudget from "../../../Server/Utils/AI/CodeFix/FixRunBudget";
|
|
3
4
|
import LlmProviderService from "../../../Server/Services/LlmProviderService";
|
|
4
5
|
import ServiceService from "../../../Server/Services/ServiceService";
|
|
@@ -79,6 +80,17 @@ function mockReadinessOk(): void {
|
|
|
79
80
|
name: "agent",
|
|
80
81
|
connectionStatus: AIAgentConnectionStatus.Connected,
|
|
81
82
|
} as unknown as AIAgent);
|
|
83
|
+
/*
|
|
84
|
+
* The llmProvider check also gates on the daily autonomous token budget
|
|
85
|
+
* (AI_CODE_FIX_FEATURE is autonomous, so executeWithLogging enforces it).
|
|
86
|
+
* Default it to unset — this suite is about the duplicate guard, and the
|
|
87
|
+
* budget has its own suite (AIServiceDailyBudget.test.ts).
|
|
88
|
+
*/
|
|
89
|
+
jest.spyOn(AIService, "getAutonomousDailyBudgetStatus").mockResolvedValue({
|
|
90
|
+
exhausted: false,
|
|
91
|
+
limitInTokens: null,
|
|
92
|
+
usedTokensToday: 0,
|
|
93
|
+
});
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
describe("TelemetryExceptionService.createCodeFixRunForException", () => {
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import Markdown from "../../../Server/Types/Markdown";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* slugify turns a heading into the `id` the docs renderer emits, and therefore
|
|
5
|
+
* into the target every in-page `](#anchor)` link has to match. These tests pin
|
|
6
|
+
* the two properties that are easy to break by accident:
|
|
7
|
+
*
|
|
8
|
+
* - non-ASCII scripts must survive (they used to be stripped to an empty id,
|
|
9
|
+
* which silently 404'd every anchor in the ru/ja/ko/hi/zh docs), and
|
|
10
|
+
* - existing English ids must not move, because they are published URLs.
|
|
11
|
+
*/
|
|
12
|
+
describe("Markdown.slugify", () => {
|
|
13
|
+
describe("English headings keep their existing ids", () => {
|
|
14
|
+
test.each([
|
|
15
|
+
[
|
|
16
|
+
"Reducing the Volume of Data Collected",
|
|
17
|
+
"reducing-the-volume-of-data-collected",
|
|
18
|
+
],
|
|
19
|
+
["Filtering by Log Severity", "filtering-by-log-severity"],
|
|
20
|
+
["Step 1 — Install the Collector", "step-1-install-the-collector"],
|
|
21
|
+
["What's New?", "whats-new"],
|
|
22
|
+
["Namespace Filtering", "namespace-filtering"],
|
|
23
|
+
])("%s", (heading: string, expected: string) => {
|
|
24
|
+
expect(Markdown.slugify(heading)).toBe(expected);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* \p{L}/\p{N} do not match "_", so it is listed explicitly in the character
|
|
30
|
+
* class. The old `\w` matched it. These are real headings — dropping the
|
|
31
|
+
* underscore would change ids that are already linked to.
|
|
32
|
+
*/
|
|
33
|
+
describe("underscores are preserved", () => {
|
|
34
|
+
test.each([
|
|
35
|
+
[
|
|
36
|
+
"`ceph_health_status` is 1 but no incident fires",
|
|
37
|
+
"ceph_health_status-is-1-but-no-incident-fires",
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
"Counters like `pve_network_receive_bytes` only ever grow",
|
|
41
|
+
"counters-like-pve_network_receive_bytes-only-ever-grow",
|
|
42
|
+
],
|
|
43
|
+
])("%s", (heading: string, expected: string) => {
|
|
44
|
+
expect(Markdown.slugify(heading)).toBe(expected);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("non-Latin scripts produce a usable id, not an empty one", () => {
|
|
49
|
+
test.each([
|
|
50
|
+
["Фильтрация по важности логов", "фильтрация-по-важности-логов"],
|
|
51
|
+
["ログの重大度によるフィルタリング", "ログの重大度によるフィルタリング"],
|
|
52
|
+
["按日志严重性过滤", "按日志严重性过滤"],
|
|
53
|
+
["로그 심각도별 필터링", "로그-심각도별-필터링"],
|
|
54
|
+
[
|
|
55
|
+
"लॉग गंभीरता के अनुसार फ़िल्टर करना",
|
|
56
|
+
"लॉग-गंभीरता-के-अनुसार-फ़िल्टर-करना",
|
|
57
|
+
],
|
|
58
|
+
])("%s", (heading: string, expected: string) => {
|
|
59
|
+
const slug: string = Markdown.slugify(heading);
|
|
60
|
+
expect(slug).not.toBe("");
|
|
61
|
+
expect(slug).toBe(expected);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("accented Latin keeps the accented letter", () => {
|
|
66
|
+
test.each([
|
|
67
|
+
[
|
|
68
|
+
"Filtrage par gravité des journaux",
|
|
69
|
+
"filtrage-par-gravité-des-journaux",
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"Reduktion af mængden af indsamlede data",
|
|
73
|
+
"reduktion-af-mængden-af-indsamlede-data",
|
|
74
|
+
],
|
|
75
|
+
["Fehlerbehebung für Größen", "fehlerbehebung-für-größen"],
|
|
76
|
+
])("%s", (heading: string, expected: string) => {
|
|
77
|
+
expect(Markdown.slugify(heading)).toBe(expected);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("markup and punctuation are still stripped", () => {
|
|
82
|
+
test("strips inline HTML tags", () => {
|
|
83
|
+
expect(Markdown.slugify("A <em>heading</em> here")).toBe(
|
|
84
|
+
"a-heading-here",
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("strips HTML entities", () => {
|
|
89
|
+
expect(Markdown.slugify("Tom & Jerry")).toBe("tom-jerry");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("strips punctuation but keeps hyphens", () => {
|
|
93
|
+
expect(Markdown.slugify("Set up SSO (SAML): step-by-step!")).toBe(
|
|
94
|
+
"set-up-sso-saml-step-by-step",
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("collapses whitespace runs and trims leading/trailing hyphens", () => {
|
|
99
|
+
expect(Markdown.slugify(" spaced out ")).toBe("spaced-out");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("emoji are dropped rather than becoming part of the id", () => {
|
|
103
|
+
expect(Markdown.slugify("🚀 Getting Started")).toBe("getting-started");
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|