@oneuptime/common 12.0.3 → 12.0.5
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/DatabaseModels/AIRun.ts +38 -1
- package/Models/DatabaseModels/AlertFeed.ts +30 -0
- package/Models/DatabaseModels/CephCluster.ts +14 -0
- package/Models/DatabaseModels/CodeRepository.ts +14 -6
- package/Models/DatabaseModels/Dashboard.ts +28 -0
- package/Models/DatabaseModels/DockerHost.ts +14 -0
- package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
- package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
- package/Models/DatabaseModels/Incident.ts +2 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentFeed.ts +30 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IoTFleet.ts +14 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
- package/Models/DatabaseModels/LogSavedView.ts +33 -0
- package/Models/DatabaseModels/NetworkDevice.ts +14 -0
- package/Models/DatabaseModels/NetworkInterface.ts +18 -0
- package/Models/DatabaseModels/Project.ts +247 -11
- package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
- package/Models/DatabaseModels/Service.ts +30 -0
- package/Models/DatabaseModels/StatusPage.ts +28 -0
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
- package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
- package/Models/DatabaseModels/User.ts +30 -0
- package/Server/API/AIAgentDataAPI.ts +75 -55
- package/Server/API/AIInvestigationAPI.ts +175 -17
- package/Server/API/DashboardAPI.ts +429 -22
- package/Server/API/GitHubAPI.ts +119 -283
- package/Server/API/StatusPageAPI.ts +38 -19
- package/Server/API/UserAPI.ts +263 -1
- package/Server/EnvironmentConfig.ts +23 -3
- package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
- package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
- package/Server/Infrastructure/GlobalCache.ts +37 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Services/AIRunService.ts +78 -10
- package/Server/Services/AIService.ts +94 -22
- package/Server/Services/AlertFeedService.ts +5 -0
- package/Server/Services/AnalyticsDatabaseService.ts +101 -1
- package/Server/Services/CodeRepositoryService.ts +105 -2
- package/Server/Services/DatabaseService.ts +227 -3
- package/Server/Services/IncidentFeedService.ts +5 -0
- package/Server/Services/LlmLogService.ts +46 -2
- package/Server/Services/OpenTelemetryIngestService.ts +230 -26
- package/Server/Services/UserService.ts +184 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
- package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
- package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
- package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
- package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
- package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
- package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
- package/Server/Utils/AI/SRE/README.md +1 -1
- package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
- package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
- package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
- package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
- package/Server/Utils/PasswordHash.ts +330 -0
- package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
- package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
- package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
- package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
- package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
- package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
- package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
- package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
- package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
- package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
- package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
- package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
- package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
- package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
- package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
- package/Tests/Server/API/Helpers.ts +6 -1
- package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +128 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
- package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
- package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
- package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
- package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +30 -1
- package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
- package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
- package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +880 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
- package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
- package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
- package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
- package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
- package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
- package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
- package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
- package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
- package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
- package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
- package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
- package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
- package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
- package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
- package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
- package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
- package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
- package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
- package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
- package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
- package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
- package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
- package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
- package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
- package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
- package/Tests/Server/Utils/PasswordHash.test.ts +585 -0
- package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
- package/Tests/Types/Database/ColumnLength.test.ts +7 -1
- package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
- package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
- package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
- package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
- package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
- package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
- package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
- package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
- package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
- package/Tests/Types/Permission.test.ts +137 -0
- package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
- package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
- package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
- package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
- package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
- package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
- package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
- package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
- package/Tests/UI/Utils/Project.test.ts +31 -0
- package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
- package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
- package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
- package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
- package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
- package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
- package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
- package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
- package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
- package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
- package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
- package/Types/AI/CodeFixTaskContext.ts +63 -3
- package/Types/AI/CodeFixTaskType.ts +3 -3
- package/Types/Database/ColumnLength.ts +9 -1
- package/Types/Database/TableColumn.ts +11 -0
- package/Types/Database/UnsynchronizedIndex.ts +48 -0
- package/Types/HashedString.ts +140 -4
- package/Types/Monitor/CriteriaFilter.ts +4 -0
- package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
- package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
- package/Types/Monitor/MonitorMetricType.ts +8 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
- package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
- package/Types/Permission.ts +23 -175
- package/Types/Probe/ProbeMonitorResponse.ts +6 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
- package/UI/Components/ErrorBoundary.tsx +138 -11
- package/UI/Components/Feed/FeedItem.tsx +9 -2
- package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
- package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
- package/UI/Components/Navbar/NavBar.tsx +12 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
- package/UI/Utils/DownloadFile.ts +16 -8
- package/UI/Utils/ErrorSupportBundle.ts +805 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
- package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
- package/UI/Utils/Project.ts +4 -0
- package/UI/Utils/StatusPage.ts +8 -2
- package/UI/Utils/UseDashboardGridDnd.ts +917 -0
- package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
- package/Utils/Dashboard/GridLayout.ts +523 -0
- package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
- package/Utils/Monitor/MonitorMetricType.ts +44 -2
- package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
- package/Utils/StatusPage/GroupTree.ts +157 -66
- package/Utils/StatusPage/ResourceUptime.ts +37 -2
- package/Utils/TeamMembersByProject.ts +237 -0
- package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
- package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
- package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
- package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +2 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
- package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +257 -13
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
- package/build/dist/Models/DatabaseModels/Service.js +28 -1
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +32 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +49 -48
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +312 -15
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GitHubAPI.js +94 -167
- package/build/dist/Server/API/GitHubAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +29 -11
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +187 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +21 -3
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.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/AIRunService.js +58 -12
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +74 -21
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertFeedService.js +3 -0
- package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +86 -2
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
- package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +180 -3
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFeedService.js +3 -0
- package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
- package/build/dist/Server/Services/LlmLogService.js +22 -1
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +165 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
- package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
- package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
- package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
- package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
- package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.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 +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/PasswordHash.js +258 -0
- package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
- package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
- package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
- package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
- package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
- package/build/dist/Types/Database/ColumnLength.js +9 -1
- package/build/dist/Types/Database/ColumnLength.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
- package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
- package/build/dist/Types/HashedString.js +96 -5
- package/build/dist/Types/HashedString.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
- package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- 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 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
- package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
- package/build/dist/Types/Permission.js +23 -155
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +67 -8
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Utils/DownloadFile.js +15 -8
- package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
- package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
- package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
- package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +3 -0
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/UI/Utils/StatusPage.js +4 -4
- package/build/dist/UI/Utils/StatusPage.js.map +1 -1
- package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
- package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
- package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
- package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
- package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
- package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
- package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
- package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/TeamMembersByProject.js +145 -0
- package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
- package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
- package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
- package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
- package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
- package/package.json +1 -1
|
@@ -168,6 +168,66 @@ const PROJECT_RETENTION_CACHE_TTL_SECONDS: number = 5 * 60;
|
|
|
168
168
|
const projectRetentionInProcessCache: Map<string, CachedRetentionContext> =
|
|
169
169
|
new Map();
|
|
170
170
|
|
|
171
|
+
/*
|
|
172
|
+
* Everything `findOrCreateTelemetryService` needs from the Service row. Cached
|
|
173
|
+
* instead of the model itself so the payload is a flat, JSON-round-trippable
|
|
174
|
+
* shape with no TypeORM entity semantics riding along.
|
|
175
|
+
*/
|
|
176
|
+
interface ServiceResolution {
|
|
177
|
+
serviceId: string;
|
|
178
|
+
retainTelemetryDataForDays: number | null;
|
|
179
|
+
telemetryRetentionConfig: TelemetryRetentionConfig | null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
interface CachedServiceResolution {
|
|
183
|
+
resolution: ServiceResolution;
|
|
184
|
+
expiresAtMs: number;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/*
|
|
188
|
+
* Per-process memo for `service.name` -> Service resolution, backed by the same
|
|
189
|
+
* L1-Map + L2-Redis pair as the project retention context above.
|
|
190
|
+
*
|
|
191
|
+
* This is the hot read on the whole ingest path and it was the one ungated
|
|
192
|
+
* operation in the function. `resolveTelemetryResource` calls it once per OTLP
|
|
193
|
+
* *resource*, not per request — the shipped host-metrics collector config
|
|
194
|
+
* produces hundreds per batch — and again for every signal type a collector
|
|
195
|
+
* exports, from every ingest pod. The per-batch `serviceDictionary` in the four
|
|
196
|
+
* Otel*IngestService files cannot help: it is written AFTER this resolves and
|
|
197
|
+
* never read before it.
|
|
198
|
+
*
|
|
199
|
+
* The uncached read was also the most expensive shape it could have been.
|
|
200
|
+
* `QueryHelper.findWithSameText` emits `LOWER("Service"."name") = $2`, and the
|
|
201
|
+
* live indexes on Service are all over the RAW name column
|
|
202
|
+
* (IDX_80cd6d06b0ab8fbce9fea6d3bc on ("projectId","name")), so Postgres can use
|
|
203
|
+
* only the `projectId` prefix as an index qual and must then heap-fetch and
|
|
204
|
+
* filter every service in the project. Cost per call is O(services in project),
|
|
205
|
+
* not O(log n). The matching expression index existed once —
|
|
206
|
+
* `("projectId", LOWER("name")) WHERE "deletedAt" IS NULL` in migration
|
|
207
|
+
* 1774559064921 — and was dropped as collateral damage by autogenerated
|
|
208
|
+
* migration 1775735059360. Restoring it is a separate change; this cache is
|
|
209
|
+
* what removes the calls in the first place.
|
|
210
|
+
*/
|
|
211
|
+
const SERVICE_RESOLUTION_CACHE_NAMESPACE: string = "service-resolution";
|
|
212
|
+
|
|
213
|
+
/*
|
|
214
|
+
* Matches the project-retention TTL deliberately: the two are read together on
|
|
215
|
+
* every resolution and there is no value in them expiring at different times.
|
|
216
|
+
*
|
|
217
|
+
* Staleness is bounded rather than invalidated, exactly as it is for project
|
|
218
|
+
* retention. A retention change made in the UI takes up to this long to affect
|
|
219
|
+
* newly ingested rows, and a service deleted in the UI keeps resolving for up
|
|
220
|
+
* to this long — which stamps `primaryEntityId` values into ClickHouse that no
|
|
221
|
+
* longer have a Postgres parent. Those rows are orphaned, not corrupt (the
|
|
222
|
+
* analytics side has no FK to Service) and they age out via retention; this is
|
|
223
|
+
* the same trade-off the dedupe migration already documents for its own
|
|
224
|
+
* ClickHouse rows. Cross-process invalidation would need pub/sub, which
|
|
225
|
+
* GlobalCache has no primitive for.
|
|
226
|
+
*/
|
|
227
|
+
const SERVICE_RESOLUTION_CACHE_TTL_SECONDS: number = 5 * 60;
|
|
228
|
+
const serviceResolutionInProcessCache: Map<string, CachedServiceResolution> =
|
|
229
|
+
new Map();
|
|
230
|
+
|
|
171
231
|
export default class OTelIngestService {
|
|
172
232
|
/*
|
|
173
233
|
* Read a single string-valued OTel resource attribute out of the raw
|
|
@@ -459,6 +519,114 @@ export default class OTelIngestService {
|
|
|
459
519
|
return result;
|
|
460
520
|
}
|
|
461
521
|
|
|
522
|
+
/*
|
|
523
|
+
* Normalises exactly as `QueryHelper.findWithSameText` does
|
|
524
|
+
* (`toLowerCase().trim()`). This has to stay in lockstep with that helper:
|
|
525
|
+
* if the key kept casing or surrounding whitespace that the SQL predicate
|
|
526
|
+
* folds away, two spellings of one `service.name` would occupy two cache
|
|
527
|
+
* entries pointing at the same row, and a batch could miss the entry the
|
|
528
|
+
* previous batch just wrote.
|
|
529
|
+
*/
|
|
530
|
+
private static getServiceResolutionCacheKey(
|
|
531
|
+
projectId: ObjectID,
|
|
532
|
+
serviceName: string,
|
|
533
|
+
): string {
|
|
534
|
+
return `${projectId.toString()}:${serviceName.toLowerCase().trim()}`;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
private static async getCachedServiceResolution(
|
|
538
|
+
cacheKey: string,
|
|
539
|
+
): Promise<ServiceResolution | null> {
|
|
540
|
+
const now: number = Date.now();
|
|
541
|
+
|
|
542
|
+
// L1: in-process memo. Zero network cost.
|
|
543
|
+
const memoed: CachedServiceResolution | undefined =
|
|
544
|
+
serviceResolutionInProcessCache.get(cacheKey);
|
|
545
|
+
if (memoed && memoed.expiresAtMs > now) {
|
|
546
|
+
return memoed.resolution;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// L2: Redis. Single round-trip; shared across workers.
|
|
550
|
+
try {
|
|
551
|
+
const cached: JSONObject | null = await GlobalCache.getJSONObject(
|
|
552
|
+
SERVICE_RESOLUTION_CACHE_NAMESPACE,
|
|
553
|
+
cacheKey,
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
/*
|
|
557
|
+
* `serviceId` is the load-bearing field — a cached entry without one
|
|
558
|
+
* cannot produce a `primaryEntityId`, so treat it as a miss and let the
|
|
559
|
+
* caller re-resolve rather than stamping rows with a broken id.
|
|
560
|
+
*/
|
|
561
|
+
if (cached && cached["serviceId"]) {
|
|
562
|
+
const resolution: ServiceResolution = {
|
|
563
|
+
serviceId: String(cached["serviceId"]),
|
|
564
|
+
retainTelemetryDataForDays:
|
|
565
|
+
(cached["retainTelemetryDataForDays"] as number | null) ?? null,
|
|
566
|
+
telemetryRetentionConfig:
|
|
567
|
+
(cached[
|
|
568
|
+
"telemetryRetentionConfig"
|
|
569
|
+
] as TelemetryRetentionConfig | null) ?? null,
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
serviceResolutionInProcessCache.set(cacheKey, {
|
|
573
|
+
resolution,
|
|
574
|
+
expiresAtMs: now + SERVICE_RESOLUTION_CACHE_TTL_SECONDS * 1000,
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
return resolution;
|
|
578
|
+
}
|
|
579
|
+
} catch (err) {
|
|
580
|
+
// Cache outage must never fail ingest. Fall through to Postgres.
|
|
581
|
+
logger.warn(
|
|
582
|
+
`Service resolution cache read failed for "${cacheKey}"; falling back to Postgres: ${
|
|
583
|
+
err instanceof Error ? err.message : String(err)
|
|
584
|
+
}`,
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
private static async cacheServiceResolution(
|
|
592
|
+
cacheKey: string,
|
|
593
|
+
resolution: ServiceResolution,
|
|
594
|
+
): Promise<void> {
|
|
595
|
+
serviceResolutionInProcessCache.set(cacheKey, {
|
|
596
|
+
resolution,
|
|
597
|
+
expiresAtMs: Date.now() + SERVICE_RESOLUTION_CACHE_TTL_SECONDS * 1000,
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
try {
|
|
601
|
+
await GlobalCache.setJSON(
|
|
602
|
+
SERVICE_RESOLUTION_CACHE_NAMESPACE,
|
|
603
|
+
cacheKey,
|
|
604
|
+
{
|
|
605
|
+
serviceId: resolution.serviceId,
|
|
606
|
+
retainTelemetryDataForDays: resolution.retainTelemetryDataForDays,
|
|
607
|
+
telemetryRetentionConfig: (resolution.telemetryRetentionConfig ??
|
|
608
|
+
null) as unknown as JSONObject,
|
|
609
|
+
},
|
|
610
|
+
{ expiresInSeconds: SERVICE_RESOLUTION_CACHE_TTL_SECONDS },
|
|
611
|
+
);
|
|
612
|
+
} catch (err) {
|
|
613
|
+
// Best-effort warm. Don't fail the request.
|
|
614
|
+
logger.warn(
|
|
615
|
+
`Service resolution cache write failed for "${cacheKey}": ${
|
|
616
|
+
err instanceof Error ? err.message : String(err)
|
|
617
|
+
}`,
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
private static toServiceResolution(service: Service): ServiceResolution {
|
|
623
|
+
return {
|
|
624
|
+
serviceId: service.id!.toString(),
|
|
625
|
+
retainTelemetryDataForDays: service.retainTelemetryDataForDays ?? null,
|
|
626
|
+
telemetryRetentionConfig: service.telemetryRetentionConfig ?? null,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
462
630
|
@CaptureSpan()
|
|
463
631
|
private static async findOrCreateTelemetryService(data: {
|
|
464
632
|
serviceName: string;
|
|
@@ -481,23 +649,38 @@ export default class OTelIngestService {
|
|
|
481
649
|
* Stored casing is preserved: service-detail pages key telemetry by the
|
|
482
650
|
* stable primaryEntityId, and the name is user-facing.
|
|
483
651
|
*/
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
652
|
+
const resolutionCacheKey: string = this.getServiceResolutionCacheKey(
|
|
653
|
+
data.projectId,
|
|
654
|
+
data.serviceName,
|
|
655
|
+
);
|
|
656
|
+
|
|
657
|
+
let resolution: ServiceResolution | null =
|
|
658
|
+
await this.getCachedServiceResolution(resolutionCacheKey);
|
|
659
|
+
|
|
660
|
+
if (!resolution) {
|
|
661
|
+
const service: Service | null = await ServiceService.findOneBy({
|
|
662
|
+
query: {
|
|
663
|
+
projectId: data.projectId,
|
|
664
|
+
name: QueryHelper.findWithSameText(data.serviceName),
|
|
665
|
+
},
|
|
666
|
+
select: {
|
|
667
|
+
_id: true,
|
|
668
|
+
retainTelemetryDataForDays: true,
|
|
669
|
+
telemetryRetentionConfig: true,
|
|
670
|
+
},
|
|
671
|
+
sort: {
|
|
672
|
+
createdAt: SortOrder.Ascending,
|
|
673
|
+
},
|
|
674
|
+
props: {
|
|
675
|
+
isRoot: true,
|
|
676
|
+
},
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
if (service) {
|
|
680
|
+
resolution = this.toServiceResolution(service);
|
|
681
|
+
await this.cacheServiceResolution(resolutionCacheKey, resolution);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
501
684
|
|
|
502
685
|
const projectContext: ProjectRetentionContext =
|
|
503
686
|
await this.getProjectRetentionContext(data.projectId);
|
|
@@ -513,14 +696,16 @@ export default class OTelIngestService {
|
|
|
513
696
|
data.serviceName,
|
|
514
697
|
);
|
|
515
698
|
|
|
516
|
-
const buildMetadata: (
|
|
517
|
-
|
|
699
|
+
const buildMetadata: (
|
|
700
|
+
resolved: ServiceResolution,
|
|
701
|
+
) => TelemetryServiceMetadata = (
|
|
702
|
+
resolved: ServiceResolution,
|
|
518
703
|
): TelemetryServiceMetadata => {
|
|
519
704
|
const serviceLevelRetention: number | null =
|
|
520
|
-
|
|
705
|
+
resolved.retainTelemetryDataForDays ?? null;
|
|
521
706
|
return {
|
|
522
707
|
serviceName: data.serviceName,
|
|
523
|
-
primaryEntityId:
|
|
708
|
+
primaryEntityId: new ObjectID(resolved.serviceId),
|
|
524
709
|
primaryEntityType: ServiceType.OpenTelemetry,
|
|
525
710
|
entityKeys: [serviceEntityKey],
|
|
526
711
|
/*
|
|
@@ -534,14 +719,14 @@ export default class OTelIngestService {
|
|
|
534
719
|
},
|
|
535
720
|
dataRententionInDays:
|
|
536
721
|
serviceLevelRetention || projectContext.projectRetentionInDays,
|
|
537
|
-
serviceRetentionConfig:
|
|
722
|
+
serviceRetentionConfig: resolved.telemetryRetentionConfig ?? null,
|
|
538
723
|
serviceRetentionInDays: serviceLevelRetention,
|
|
539
724
|
projectRetentionConfig: projectContext.projectRetentionConfig,
|
|
540
725
|
projectRetentionInDays: projectContext.projectRetentionInDays,
|
|
541
726
|
};
|
|
542
727
|
};
|
|
543
728
|
|
|
544
|
-
if (!
|
|
729
|
+
if (!resolution) {
|
|
545
730
|
try {
|
|
546
731
|
const newService: Service = new Service();
|
|
547
732
|
newService.projectId = data.projectId;
|
|
@@ -555,11 +740,23 @@ export default class OTelIngestService {
|
|
|
555
740
|
},
|
|
556
741
|
});
|
|
557
742
|
|
|
558
|
-
|
|
743
|
+
const createdResolution: ServiceResolution =
|
|
744
|
+
this.toServiceResolution(createdService);
|
|
745
|
+
await this.cacheServiceResolution(
|
|
746
|
+
resolutionCacheKey,
|
|
747
|
+
createdResolution,
|
|
748
|
+
);
|
|
749
|
+
|
|
750
|
+
return buildMetadata(createdResolution);
|
|
559
751
|
} catch {
|
|
560
752
|
/*
|
|
561
753
|
* Race condition: another request created the service concurrently.
|
|
562
754
|
* Re-fetch the existing service (oldest wins, see sort above).
|
|
755
|
+
*
|
|
756
|
+
* This refetch emits SQL byte-identical to the lookup above, so it is
|
|
757
|
+
* indistinguishable from it in pg_stat_activity — caching the result
|
|
758
|
+
* here matters as much as caching it there. A first-contact stampede
|
|
759
|
+
* on a brand-new service.name is exactly when this branch runs hot.
|
|
563
760
|
*/
|
|
564
761
|
const existingService: Service | null = await ServiceService.findOneBy({
|
|
565
762
|
query: {
|
|
@@ -580,7 +777,14 @@ export default class OTelIngestService {
|
|
|
580
777
|
});
|
|
581
778
|
|
|
582
779
|
if (existingService) {
|
|
583
|
-
|
|
780
|
+
const existingResolution: ServiceResolution =
|
|
781
|
+
this.toServiceResolution(existingService);
|
|
782
|
+
await this.cacheServiceResolution(
|
|
783
|
+
resolutionCacheKey,
|
|
784
|
+
existingResolution,
|
|
785
|
+
);
|
|
786
|
+
|
|
787
|
+
return buildMetadata(existingResolution);
|
|
584
788
|
}
|
|
585
789
|
|
|
586
790
|
throw new Error(
|
|
@@ -589,7 +793,7 @@ export default class OTelIngestService {
|
|
|
589
793
|
}
|
|
590
794
|
}
|
|
591
795
|
|
|
592
|
-
return buildMetadata(
|
|
796
|
+
return buildMetadata(resolution);
|
|
593
797
|
}
|
|
594
798
|
|
|
595
799
|
/*
|
|
@@ -24,6 +24,9 @@ import URL from "../../Types/API/URL";
|
|
|
24
24
|
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
25
25
|
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
26
26
|
import OneUptimeDate from "../../Types/Date";
|
|
27
|
+
import PositiveNumber from "../../Types/PositiveNumber";
|
|
28
|
+
import ProjectService from "./ProjectService";
|
|
29
|
+
import Semaphore, { SemaphoreMutex } from "../Infrastructure/Semaphore";
|
|
27
30
|
import Email from "../../Types/Email";
|
|
28
31
|
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
29
32
|
import HashedString from "../../Types/HashedString";
|
|
@@ -45,6 +48,37 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
|
45
48
|
import Timezone from "../../Types/Timezone";
|
|
46
49
|
import InMemoryTTLCache from "../Infrastructure/InMemoryTTLCache";
|
|
47
50
|
|
|
51
|
+
/*
|
|
52
|
+
* Names the Redis mutex that serializes the first-Master-Admin election across
|
|
53
|
+
* every process on this instance. Namespaced the same way as the other
|
|
54
|
+
* cross-process mutexes in this codebase (see ProjectService's counter locks)
|
|
55
|
+
* so the key is self-documenting in Redis and cannot collide with another lock.
|
|
56
|
+
*/
|
|
57
|
+
const FIRST_MASTER_ADMIN_ELECTION_LOCK_NAMESPACE: string =
|
|
58
|
+
"UserService.firstMasterAdminElection";
|
|
59
|
+
const FIRST_MASTER_ADMIN_ELECTION_LOCK_KEY: string = "instance";
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* How long the mutex survives without being refreshed. This is a crash bound,
|
|
63
|
+
* NOT a work budget: redis-semaphore refreshes an held lock every
|
|
64
|
+
* 0.8 * lockTimeout for as long as the holder is alive, so a slow COUNT+INSERT
|
|
65
|
+
* does not expire the lock out from under itself. It only matters when a holder
|
|
66
|
+
* dies mid-election (SIGKILL, eviction) — the lock then frees itself after this
|
|
67
|
+
* long instead of wedging every subsequent signup on the instance forever.
|
|
68
|
+
*/
|
|
69
|
+
const FIRST_MASTER_ADMIN_ELECTION_LOCK_TIMEOUT_MS: number = 10_000;
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
* How long a signup waits for the lock before giving up. Signup is a
|
|
73
|
+
* user-facing request, so the wait has to be bounded rather than indefinite —
|
|
74
|
+
* this replaces the bound that Postgres `lock_timeout` used to give us.
|
|
75
|
+
*
|
|
76
|
+
* Failing the signup is the correct outcome when it fires: refusing to serve
|
|
77
|
+
* one request is safe, serving it unserialized is exactly the bug this lock
|
|
78
|
+
* exists to prevent (GHSA-3qqq-hprx-g2jw).
|
|
79
|
+
*/
|
|
80
|
+
const FIRST_MASTER_ADMIN_ELECTION_ACQUIRE_TIMEOUT_MS: number = 5_000;
|
|
81
|
+
|
|
48
82
|
export class Service extends DatabaseService<Model> {
|
|
49
83
|
/*
|
|
50
84
|
* Suppresses repeated `lastActive` UPDATEs from a single API node. 60s of
|
|
@@ -499,6 +533,156 @@ export class Service extends DatabaseService<Model> {
|
|
|
499
533
|
return onUpdate;
|
|
500
534
|
}
|
|
501
535
|
|
|
536
|
+
/**
|
|
537
|
+
* Creates a user who is signing themselves up, and decides — atomically —
|
|
538
|
+
* whether they are the instance's very first Master Admin.
|
|
539
|
+
*
|
|
540
|
+
* Every signup MUST come through here rather than calling `create` directly,
|
|
541
|
+
* because this method is the only place that is allowed to set
|
|
542
|
+
* `isMasterAdmin` on a self-service signup. It always assigns the column, so
|
|
543
|
+
* an `isMasterAdmin: true` smuggled into the request body is overwritten
|
|
544
|
+
* rather than honoured (signup creates with `isRoot: true`, which bypasses
|
|
545
|
+
* the column's empty `create: []` access control).
|
|
546
|
+
*/
|
|
547
|
+
@CaptureSpan()
|
|
548
|
+
public async createUserOnSignup(data: {
|
|
549
|
+
user: Model;
|
|
550
|
+
props: DatabaseCommonInteractionProps;
|
|
551
|
+
}): Promise<Model> {
|
|
552
|
+
// Never inherited from the caller. Decided below, or not at all.
|
|
553
|
+
data.user.isMasterAdmin = false;
|
|
554
|
+
|
|
555
|
+
if (IsBillingEnabled) {
|
|
556
|
+
/*
|
|
557
|
+
* On the hosted service there is no first-user bootstrap: master admins
|
|
558
|
+
* are provisioned out of band, so there is nothing to elect and no reason
|
|
559
|
+
* to take a lock.
|
|
560
|
+
*/
|
|
561
|
+
return await this.create({
|
|
562
|
+
data: data.user,
|
|
563
|
+
props: data.props,
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/*
|
|
568
|
+
* Self-hosted: the first user to sign up bootstraps the instance as Master
|
|
569
|
+
* Admin. The eligibility check reads the User table and the create writes to
|
|
570
|
+
* it, which is a read-then-write and therefore not atomic on its own — two
|
|
571
|
+
* signups landing together both counted zero users and both became Master
|
|
572
|
+
* Admin (GHSA-3qqq-hprx-g2jw). Serialize the check and the insert
|
|
573
|
+
* instance-wide so the second request observes the first one's row.
|
|
574
|
+
*
|
|
575
|
+
* The mutex is the Redis one every other cross-process critical section in
|
|
576
|
+
* this codebase uses (Semaphore), not a Postgres advisory lock. It holds no
|
|
577
|
+
* database connection and no open transaction, so serializing signups
|
|
578
|
+
* cannot pin a pooled backend `idle in transaction`, and it is unaffected
|
|
579
|
+
* by how PgBouncer is pooling.
|
|
580
|
+
*/
|
|
581
|
+
let mutex: SemaphoreMutex;
|
|
582
|
+
|
|
583
|
+
try {
|
|
584
|
+
mutex = await Semaphore.lock({
|
|
585
|
+
key: FIRST_MASTER_ADMIN_ELECTION_LOCK_KEY,
|
|
586
|
+
namespace: FIRST_MASTER_ADMIN_ELECTION_LOCK_NAMESPACE,
|
|
587
|
+
lockTimeout: FIRST_MASTER_ADMIN_ELECTION_LOCK_TIMEOUT_MS,
|
|
588
|
+
acquireTimeout: FIRST_MASTER_ADMIN_ELECTION_ACQUIRE_TIMEOUT_MS,
|
|
589
|
+
});
|
|
590
|
+
} catch (err) {
|
|
591
|
+
/*
|
|
592
|
+
* Redis unreachable, or the lock stayed contended past the acquire
|
|
593
|
+
* timeout. Fail the signup rather than fall back to an unserialized
|
|
594
|
+
* election — the fallback is the vulnerability.
|
|
595
|
+
*/
|
|
596
|
+
logger.error(
|
|
597
|
+
"Refusing to create a signup: could not acquire the first-Master-Admin election lock.",
|
|
598
|
+
);
|
|
599
|
+
logger.error(err);
|
|
600
|
+
|
|
601
|
+
throw err;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/*
|
|
605
|
+
* The critical section deliberately covers the INSERT, not just the count:
|
|
606
|
+
* releasing after the count would let the next holder count a table the
|
|
607
|
+
* winner had not written to yet, which is the same race with extra steps.
|
|
608
|
+
*
|
|
609
|
+
* `finally` so a failed create still frees the lock immediately instead of
|
|
610
|
+
* blocking every other signup until lockTimeout elapses.
|
|
611
|
+
*/
|
|
612
|
+
try {
|
|
613
|
+
data.user.isMasterAdmin = await this.isInstanceAwaitingFirstUser();
|
|
614
|
+
|
|
615
|
+
return await this.create({
|
|
616
|
+
data: data.user,
|
|
617
|
+
props: data.props,
|
|
618
|
+
});
|
|
619
|
+
} finally {
|
|
620
|
+
try {
|
|
621
|
+
await Semaphore.release(mutex);
|
|
622
|
+
} catch (err) {
|
|
623
|
+
/*
|
|
624
|
+
* Best-effort and non-masking: an error here must not replace the
|
|
625
|
+
* outcome of the signup, and an unreleased lock still expires on its
|
|
626
|
+
* own after lockTimeout.
|
|
627
|
+
*/
|
|
628
|
+
logger.error(
|
|
629
|
+
"Failed to release the first-Master-Admin election lock; it will expire on its own.",
|
|
630
|
+
);
|
|
631
|
+
logger.error(err);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Is this a brand-new instance that nobody has ever signed up to — i.e. may
|
|
638
|
+
* the next user through the door take Master Admin?
|
|
639
|
+
*
|
|
640
|
+
* Only ever called while holding the first-Master-Admin election mutex.
|
|
641
|
+
*/
|
|
642
|
+
private async isInstanceAwaitingFirstUser(): Promise<boolean> {
|
|
643
|
+
const userCount: PositiveNumber = await this.countBy({
|
|
644
|
+
props: {
|
|
645
|
+
isRoot: true,
|
|
646
|
+
},
|
|
647
|
+
query: {},
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
if (!userCount.isZero()) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/*
|
|
655
|
+
* Zero users, but projects exist: this is not a fresh install, it is an
|
|
656
|
+
* instance whose User table was emptied out from under it — a bad restore, a
|
|
657
|
+
* cleanup script, a cascade. Handing Master Admin to whoever signs up next
|
|
658
|
+
* would be a free promotion for a stranger, so refuse and make the operator
|
|
659
|
+
* grant it deliberately.
|
|
660
|
+
*
|
|
661
|
+
* This cannot fire on any supported path: a user who belongs to a project
|
|
662
|
+
* cannot be deleted (see onBeforeDelete), so "projects with no users at all"
|
|
663
|
+
* is only reachable by writing to the database directly. It does not get in
|
|
664
|
+
* the way of the ordinary recovery either — someone who signs up, has no
|
|
665
|
+
* projects yet, deletes their account and signs up again still bootstraps
|
|
666
|
+
* normally.
|
|
667
|
+
*/
|
|
668
|
+
const projectCount: PositiveNumber = await ProjectService.countBy({
|
|
669
|
+
props: {
|
|
670
|
+
isRoot: true,
|
|
671
|
+
},
|
|
672
|
+
query: {},
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
if (!projectCount.isZero()) {
|
|
676
|
+
logger.warn(
|
|
677
|
+
"Refusing to grant Master Admin to a new signup: the User table is empty but this instance already has projects. Grant Master Admin explicitly instead.",
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
return true;
|
|
684
|
+
}
|
|
685
|
+
|
|
502
686
|
@CaptureSpan()
|
|
503
687
|
public async createByEmail(data: {
|
|
504
688
|
email: Email;
|
|
@@ -59,6 +59,9 @@ export interface ObservabilityAssistantStep {
|
|
|
59
59
|
export interface ObservabilityAssistantRequest {
|
|
60
60
|
projectId: ObjectID;
|
|
61
61
|
userId?: ObjectID | undefined;
|
|
62
|
+
incidentId?: ObjectID | undefined;
|
|
63
|
+
alertId?: ObjectID | undefined;
|
|
64
|
+
aiRunId?: ObjectID | undefined;
|
|
62
65
|
// The requesting user's real permission props — tools run under these.
|
|
63
66
|
props: DatabaseCommonInteractionProps;
|
|
64
67
|
question: string;
|
|
@@ -230,6 +233,9 @@ export default class ObservabilityAssistant {
|
|
|
230
233
|
const response: AILogResponse = await AIService.executeWithLogging({
|
|
231
234
|
projectId: request.projectId,
|
|
232
235
|
userId: request.userId,
|
|
236
|
+
incidentId: request.incidentId,
|
|
237
|
+
alertId: request.alertId,
|
|
238
|
+
aiRunId: request.aiRunId,
|
|
233
239
|
llmProviderId: request.llmProviderId,
|
|
234
240
|
feature: request.feature,
|
|
235
241
|
messages: messages,
|
|
@@ -130,6 +130,8 @@ export default class CodeFixAgentCompletion {
|
|
|
130
130
|
runType: true,
|
|
131
131
|
status: true,
|
|
132
132
|
aiAgentId: true,
|
|
133
|
+
triggeredByIncidentId: true,
|
|
134
|
+
triggeredByAlertId: true,
|
|
133
135
|
},
|
|
134
136
|
props: {
|
|
135
137
|
isRoot: true,
|
|
@@ -198,6 +200,8 @@ export default class CodeFixAgentCompletion {
|
|
|
198
200
|
projectId: run.projectId,
|
|
199
201
|
feature: AI_CODE_FIX_FEATURE,
|
|
200
202
|
aiRunId: request.aiRunId,
|
|
203
|
+
incidentId: run.triggeredByIncidentId,
|
|
204
|
+
alertId: run.triggeredByAlertId,
|
|
201
205
|
llmProviderId: llmProvider.id,
|
|
202
206
|
messages: request.messages,
|
|
203
207
|
tools: request.tools,
|
|
@@ -102,9 +102,12 @@ export default class CodeFixReadiness {
|
|
|
102
102
|
* self-hosted too, where a project-owned provider makes the balance gate
|
|
103
103
|
* moot and this becomes the ONLY thing that can kill a run.
|
|
104
104
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
105
|
+
* These readiness surfaces create subjectless exception/general tasks, so
|
|
106
|
+
* they use the "Other AI Workload" token lane. Incident/alert fix paths
|
|
107
|
+
* enforce their own lane when they are triggered and on every completion.
|
|
108
|
+
* A limit of 0 is a documented kill-switch for this lane, so without this
|
|
109
|
+
* a paused project would read "ready" forever while every subjectless run
|
|
110
|
+
* died at its first completion call.
|
|
108
111
|
*/
|
|
109
112
|
const budget: AutonomousBudgetStatus =
|
|
110
113
|
await AIService.getAutonomousDailyBudgetStatus(params.projectId);
|
|
@@ -116,8 +119,8 @@ export default class CodeFixReadiness {
|
|
|
116
119
|
title: "LLM provider",
|
|
117
120
|
detail:
|
|
118
121
|
budget.limitInTokens !== null && budget.limitInTokens <= 0
|
|
119
|
-
? "AI is paused for this project: the daily
|
|
120
|
-
: `The daily
|
|
122
|
+
? "Other autonomous AI work is paused for this project: the daily background AI token limit is set to 0. Raise or unset it under Project Settings > AI > AI Guardrails to let subjectless fix tasks run."
|
|
123
|
+
: `The daily background AI token budget is exhausted (${budget.usedTokensToday.toLocaleString()} of ${budget.limitInTokens?.toLocaleString()} tokens used today). Subjectless fix tasks resume tomorrow (UTC) — raise or unset the limit under Project Settings > AI > AI Guardrails.`,
|
|
121
124
|
};
|
|
122
125
|
}
|
|
123
126
|
|