@oneuptime/common 14.0.9 → 14.0.11
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/AIConversation.ts +127 -1
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
- package/Models/DatabaseModels/CephCluster.ts +225 -0
- package/Models/DatabaseModels/CloudResource.ts +12 -0
- package/Models/DatabaseModels/DatabaseServer.ts +225 -0
- package/Models/DatabaseModels/DockerHost.ts +225 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +225 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/GlobalOidc.ts +0 -4
- package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
- package/Models/DatabaseModels/GlobalSso.ts +0 -4
- package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
- package/Models/DatabaseModels/Host.ts +225 -0
- package/Models/DatabaseModels/IncidentForm.ts +594 -0
- package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/IoTFleet.ts +12 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
- package/Models/DatabaseModels/MessageQueue.ts +1102 -0
- package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
- package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
- package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
- package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
- package/Models/DatabaseModels/PodmanHost.ts +225 -0
- package/Models/DatabaseModels/Project.ts +59 -0
- package/Models/DatabaseModels/ProjectOidc.ts +0 -4
- package/Models/DatabaseModels/ProjectSso.ts +0 -4
- package/Models/DatabaseModels/ProxmoxCluster.ts +225 -0
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RumApplication.ts +12 -0
- package/Models/DatabaseModels/RunnerJob.ts +144 -0
- package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
- package/Models/DatabaseModels/Service.ts +12 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
- package/Models/DatabaseModels/StatusPageSso.ts +0 -4
- package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
- package/Models/DatabaseModels/VMwareVCenter.ts +225 -0
- package/Server/API/AIChatAPI.ts +13 -114
- package/Server/API/AIInvestigationAPI.ts +3 -3
- package/Server/API/AIInvestigationConversationAPI.ts +266 -0
- package/Server/API/AutoRemediationAPI.ts +392 -1
- package/Server/API/IncidentFormAPI.ts +376 -0
- package/Server/API/ProjectOIDC.ts +16 -25
- package/Server/API/ProjectSSO.ts +16 -24
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- package/Server/API/StatusPageAPI.ts +42 -77
- package/Server/Enterprise/EnterpriseEdition.ts +93 -28
- package/Server/Enterprise/EnterpriseFeature.ts +25 -3
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
- package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
- package/Server/EnvironmentConfig.ts +1 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
- package/Server/Middleware/TelemetryIngest.ts +15 -5
- package/Server/Middleware/UserAuthorization.ts +16 -38
- package/Server/Services/AIService.ts +10 -13
- package/Server/Services/AnalyticsDatabaseService.ts +45 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
- package/Server/Services/CephClusterService.ts +109 -1
- package/Server/Services/DatabaseServerService.ts +116 -1
- package/Server/Services/DockerHostService.ts +109 -1
- package/Server/Services/DockerSwarmClusterService.ts +113 -1
- package/Server/Services/HostService.ts +126 -4
- package/Server/Services/IncidentCustomFieldService.ts +112 -2
- package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
- package/Server/Services/IncidentEpisodeService.ts +10 -1
- package/Server/Services/IncidentFormService.ts +1566 -0
- package/Server/Services/IncidentFormSubmissionService.ts +97 -0
- package/Server/Services/IncidentGroupingEngineService.ts +45 -8
- package/Server/Services/IncidentService.ts +123 -5
- package/Server/Services/IncidentTemplateService.ts +22 -0
- package/Server/Services/Index.ts +14 -0
- package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
- package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
- package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
- package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
- package/Server/Services/MessageQueueService.ts +1463 -0
- package/Server/Services/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/OpenTelemetryIngestService.ts +37 -4
- package/Server/Services/PodmanHostService.ts +109 -1
- package/Server/Services/ProjectService.ts +0 -59
- package/Server/Services/ProxmoxClusterService.ts +110 -1
- package/Server/Services/ResourceAiAccessService.ts +1439 -0
- package/Server/Services/ResourceAiAgentJobService.ts +202 -0
- package/Server/Services/ResourceAiAgentService.ts +2432 -0
- package/Server/Services/RunnerJobService.ts +611 -4
- package/Server/Services/StatusPagePrivateUserService.ts +1 -4
- package/Server/Services/StatusPageService.ts +1 -51
- package/Server/Services/TeamComplianceSettingService.ts +163 -42
- package/Server/Services/TelemetryUsageBillingService.ts +28 -0
- package/Server/Services/TraceRecordingRuleService.ts +33 -0
- package/Server/Services/UserNotificationRuleService.ts +8 -1
- package/Server/Services/VMwareVCenterService.ts +110 -1
- package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
- package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
- package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
- package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
- package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
- package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1442 -34
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +968 -34
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +622 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +882 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +125 -12
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +99 -15
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +99 -15
- package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
- package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
- package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
- package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
- package/Server/Utils/EditionEnforcement.ts +19 -202
- package/Server/Utils/LLM/LLMService.ts +259 -63
- package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
- package/Server/Utils/SameOriginRequest.ts +203 -0
- package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
- package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
- package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
- package/Server/Utils/VendorAssets.ts +3 -3
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +301 -225
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +38 -16
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +376 -144
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
- package/Tests/App/Accounts/IncidentFormPage.test.tsx +2036 -0
- package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
- package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
- package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
- package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
- package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
- package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
- package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
- package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +267 -12
- package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
- package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
- package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +23 -6
- package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
- package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
- package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
- package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
- package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
- package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
- package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
- package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
- package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
- package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
- package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
- package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
- package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
- package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
- package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
- package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
- package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
- package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
- package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
- package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
- package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
- package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
- package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
- package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
- package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
- package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
- package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
- package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
- package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
- package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
- package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
- package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
- package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
- package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
- package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
- package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
- package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
- package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
- package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
- package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
- package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
- package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
- package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
- package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
- package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
- package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
- package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
- package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
- package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
- package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
- package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
- package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +555 -0
- package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +2010 -0
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1455 -0
- package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
- package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
- package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
- package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
- package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
- package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
- package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
- package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
- package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
- package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
- package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
- package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
- package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
- package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
- package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
- package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +61 -10
- package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
- package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
- package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
- package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
- package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
- package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
- package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
- package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
- package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
- package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
- package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
- package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
- package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
- package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
- package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
- package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
- package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
- package/Tests/Server/Services/IncidentCreatedFeedTitle.test.ts +212 -0
- package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
- package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
- package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
- package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
- package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
- package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
- package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
- package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
- package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
- package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
- package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
- package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
- package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
- package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
- package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
- package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
- package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
- package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
- package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
- package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
- package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
- package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
- package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
- package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
- package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
- package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
- package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
- package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
- package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
- package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
- package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
- package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
- package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
- package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
- package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
- package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
- package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
- package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
- package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
- package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
- package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
- package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
- package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
- package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +694 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
- package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
- package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
- package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
- package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
- package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1251 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
- package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +1004 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +834 -0
- package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
- package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
- package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
- package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
- package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
- package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
- package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +20 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
- package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
- package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
- package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
- package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
- package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
- package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
- package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
- package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
- package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
- package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
- package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
- package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
- package/Tests/Types/Monitor/MetricEngineFold.ts +154 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
- package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
- package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +519 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
- package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
- package/Tests/Types/XML.test.ts +51 -0
- package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
- package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
- package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
- package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
- package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
- package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
- package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
- package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
- package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
- package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
- package/Tests/UI/Components/Icon.test.tsx +32 -0
- package/Tests/UI/Components/Input.test.tsx +31 -0
- package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
- package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
- package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
- package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
- package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
- package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
- package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
- package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
- package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
- package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
- package/Tests/UI/Components/TextArea.test.tsx +19 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
- package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
- package/Tests/UI/EsbuildConfig.test.ts +115 -39
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
- package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -0
- package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
- package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
- package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
- package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
- package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
- package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
- package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
- package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
- package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
- package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
- package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
- package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
- package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
- package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
- package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/AIAgentRunLimits.ts +146 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
- package/Types/Code/CodeType.ts +2 -0
- package/Types/Code/JsonSyntax.ts +923 -0
- package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
- package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
- package/Types/Icon/IconProp.ts +2 -0
- package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
- package/Types/Incident/IncidentFormPublic.ts +1145 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
- package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
- package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
- package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
- package/Types/MessageQueue/MessagingSystem.ts +518 -0
- package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
- package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
- package/Types/Monitor/RumAlertTemplates.ts +351 -4
- package/Types/Permission.ts +310 -0
- package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +580 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- package/Types/Rules/RuleRun.ts +4 -0
- package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
- package/Types/Runbook/RunbookStepType.ts +29 -0
- package/Types/Team/ComplianceNotificationChannel.ts +4 -3
- package/Types/Team/ComplianceRule.ts +71 -18
- package/Types/Team/ComplianceRuleType.ts +2 -2
- package/Types/Team/TeamComplianceStatus.ts +6 -2
- package/Types/Telemetry/EntityType.ts +16 -0
- package/Types/Telemetry/LockedFilterDetail.ts +22 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
- package/Types/XML.ts +26 -0
- package/UI/Components/CodeEditor/CodeEditor.css +379 -0
- package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
- package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
- package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
- package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
- package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
- package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
- package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
- package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
- package/UI/Components/Forms/Fields/FormField.tsx +8 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Icon/Icon.tsx +18 -0
- package/UI/Components/Input/Input.tsx +11 -4
- package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
- package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
- package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
- package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
- package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
- package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
- package/UI/Components/Table/EmptyTableMessage.ts +81 -0
- package/UI/Components/Table/Table.tsx +50 -21
- package/UI/Components/Table/TableRow.tsx +9 -1
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
- package/UI/Components/TextArea/TextArea.tsx +9 -2
- package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
- package/UI/Styles/Theme.css +8 -0
- package/UI/esbuild-config.js +2 -32
- package/Utils/AI/InvestigationReport.ts +121 -15
- package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
- package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
- package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
- package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
- package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
- package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
- package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
- package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
- package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
- package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
- package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
- package/Utils/LabelRuleImportExport.ts +2 -0
- package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
- package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
- package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
- package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
- package/Utils/Telemetry/EntityKey.ts +48 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
- package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +231 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +231 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +231 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
- package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
- package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js +231 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +61 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +12 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +231 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -103
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
- package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
- package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentFormAPI.js +245 -0
- package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
- package/build/dist/Server/API/ProjectOIDC.js +16 -24
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +16 -24
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
- package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +42 -75
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js +63 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js +559 -0
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +10 -13
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +104 -0
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseServerService.js +99 -0
- package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +104 -0
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +114 -2
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +83 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFormService.js +1202 -0
- package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +106 -4
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +14 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueService.js +1140 -0
- package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +104 -0
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +0 -54
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
- package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/RunnerJobService.js +344 -5
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +0 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
- package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +8 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
- package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +12 -3
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1036 -32
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +661 -41
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +354 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +602 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +90 -14
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +73 -10
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +73 -10
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/EditionEnforcement.js +20 -158
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
- package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +3 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +186 -210
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +22 -16
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +273 -111
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
- package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
- package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +116 -29
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/Code/CodeType.js +2 -0
- package/build/dist/Types/Code/CodeType.js.map +1 -1
- package/build/dist/Types/Code/JsonSyntax.js +604 -0
- package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
- package/build/dist/Types/Icon/IconProp.js +2 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Permission.js +274 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +281 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +4 -3
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRule.js +48 -14
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
- package/build/dist/Types/Telemetry/EntityType.js +16 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/Types/XML.js +23 -0
- package/build/dist/Types/XML.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +8 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +11 -3
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
- package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
- package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +30 -11
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +9 -2
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
- package/build/dist/Utils/AI/InvestigationReport.js +71 -11
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
- package/build/dist/Utils/LabelRuleImportExport.js +2 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/package.json +1 -3
- package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
- package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
- package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
- package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
- package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
- package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
- package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
- package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
- package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
- package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
|
@@ -11,7 +11,10 @@ import TeamComplianceSettingService, {
|
|
|
11
11
|
DeletedSeverity,
|
|
12
12
|
DUPLICATE_COMPLIANCE_RULE_MESSAGE,
|
|
13
13
|
SEVERITIES_DELETED_ENABLE_MESSAGE,
|
|
14
|
+
StoredChannelColumns,
|
|
15
|
+
TeamComplianceSettingService as TeamComplianceSettingRules,
|
|
14
16
|
} from "../../../Server/Services/TeamComplianceSettingService";
|
|
17
|
+
import { AddTeamComplianceRuleNotificationChannels1796500000000 } from "../../../Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels";
|
|
15
18
|
import UpdateBy from "../../../Server/Types/Database/UpdateBy";
|
|
16
19
|
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
17
20
|
import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
|
|
@@ -22,18 +25,22 @@ import Permission, {
|
|
|
22
25
|
UserTenantAccessPermission,
|
|
23
26
|
} from "../../../Types/Permission";
|
|
24
27
|
import ComplianceNotificationChannel from "../../../Types/Team/ComplianceNotificationChannel";
|
|
25
|
-
import {
|
|
28
|
+
import ComplianceRule, {
|
|
29
|
+
ComplianceSeverityKind,
|
|
30
|
+
} from "../../../Types/Team/ComplianceRule";
|
|
26
31
|
import ComplianceRuleType from "../../../Types/Team/ComplianceRuleType";
|
|
27
32
|
import UserType from "../../../Types/UserType";
|
|
28
|
-
import { DataSource, Logger } from "typeorm";
|
|
33
|
+
import { DataSource, Logger, QueryRunner } from "typeorm";
|
|
29
34
|
|
|
30
35
|
/*
|
|
31
|
-
* Team compliance rules scoped by severity and
|
|
32
|
-
* (TeamComplianceSetting.
|
|
36
|
+
* Team compliance rules scoped by severity and channels
|
|
37
|
+
* (TeamComplianceSetting.notificationChannels - with notificationChannel,
|
|
38
|
+
* the older single column kept in step with it - incidentSeverities and
|
|
33
39
|
* alertSeverities) against a migrated Postgres.
|
|
34
40
|
*
|
|
35
41
|
* Opt in with RUN_POSTGRES_TEAM_COMPLIANCE_TESTS=true against a database the
|
|
36
|
-
* registered migrations (1796000000000-AddTeamComplianceRuleScope
|
|
42
|
+
* registered migrations (1796000000000-AddTeamComplianceRuleScope and
|
|
43
|
+
* 1796500000000-AddTeamComplianceRuleNotificationChannels included)
|
|
37
44
|
* have been applied to, e.g. from packages/Common:
|
|
38
45
|
*
|
|
39
46
|
* RUN_POSTGRES_TEAM_COMPLIANCE_TESTS=true \
|
|
@@ -122,6 +129,12 @@ type SeverityList = Array<
|
|
|
122
129
|
|
|
123
130
|
interface RuleInput {
|
|
124
131
|
ruleType: ComplianceRuleType;
|
|
132
|
+
// What the Dashboard's rule form sends.
|
|
133
|
+
notificationChannels?:
|
|
134
|
+
| Array<ComplianceNotificationChannel>
|
|
135
|
+
| null
|
|
136
|
+
| undefined;
|
|
137
|
+
// What a client from before the list sends instead.
|
|
125
138
|
notificationChannel?: ComplianceNotificationChannel | null | undefined;
|
|
126
139
|
incidentSeverities?: SeverityList | undefined;
|
|
127
140
|
alertSeverities?: SeverityList | undefined;
|
|
@@ -130,10 +143,14 @@ interface RuleInput {
|
|
|
130
143
|
projectId?: ObjectID | undefined;
|
|
131
144
|
}
|
|
132
145
|
|
|
133
|
-
|
|
146
|
+
/*
|
|
147
|
+
* A rule row as Postgres stores it, with its join rows. `notificationChannels`
|
|
148
|
+
* is what the row checks, read off its two channel columns the way the
|
|
149
|
+
* service reads them (getStoredChannels).
|
|
150
|
+
*/
|
|
134
151
|
interface StoredRule {
|
|
135
152
|
ruleType: string;
|
|
136
|
-
|
|
153
|
+
notificationChannels: Array<string>;
|
|
137
154
|
enabled: boolean;
|
|
138
155
|
incidentSeverityIds: Array<string>;
|
|
139
156
|
alertSeverityIds: Array<string>;
|
|
@@ -485,6 +502,10 @@ describePostgres(
|
|
|
485
502
|
unknown
|
|
486
503
|
>;
|
|
487
504
|
|
|
505
|
+
if (input.notificationChannels !== undefined) {
|
|
506
|
+
raw["notificationChannels"] = input.notificationChannels;
|
|
507
|
+
}
|
|
508
|
+
|
|
488
509
|
if (input.notificationChannel !== undefined) {
|
|
489
510
|
raw["notificationChannel"] = input.notificationChannel;
|
|
490
511
|
}
|
|
@@ -544,9 +565,27 @@ describePostgres(
|
|
|
544
565
|
});
|
|
545
566
|
}
|
|
546
567
|
|
|
568
|
+
// The two channel columns exactly as Postgres holds them.
|
|
569
|
+
async function storedChannelColumns(
|
|
570
|
+
settingId: ObjectID,
|
|
571
|
+
): Promise<StoredChannelColumns> {
|
|
572
|
+
const rows: Array<SqlRow> = await database.query(
|
|
573
|
+
`SELECT "notificationChannels", "notificationChannel", jsonb_typeof("notificationChannels") AS "listType" FROM "${schema}"."TeamComplianceSetting" WHERE "_id" = $1`,
|
|
574
|
+
[settingId.toString()],
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
// A list is stored as a jsonb ARRAY - never a string holding one.
|
|
578
|
+
expect([null, "array"]).toContain(rows[0]?.["listType"] ?? null);
|
|
579
|
+
|
|
580
|
+
return {
|
|
581
|
+
notificationChannels: rows[0]?.["notificationChannels"] ?? null,
|
|
582
|
+
notificationChannel: rows[0]?.["notificationChannel"] ?? null,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
547
586
|
async function stored(settingId: ObjectID): Promise<StoredRule | null> {
|
|
548
587
|
const rows: Array<SqlRow> = await database.query(
|
|
549
|
-
`SELECT "ruleType", "
|
|
588
|
+
`SELECT "ruleType", "enabled" FROM "${schema}"."TeamComplianceSetting" WHERE "_id" = $1`,
|
|
550
589
|
[settingId.toString()],
|
|
551
590
|
);
|
|
552
591
|
|
|
@@ -554,12 +593,29 @@ describePostgres(
|
|
|
554
593
|
return null;
|
|
555
594
|
}
|
|
556
595
|
|
|
596
|
+
/*
|
|
597
|
+
* Every row the service writes keeps its two channel columns in step:
|
|
598
|
+
* either neither was ever written, or the list is canonical and the
|
|
599
|
+
* single column holds its first channel - which an older build reading
|
|
600
|
+
* only that column relies on.
|
|
601
|
+
*/
|
|
602
|
+
const columns: StoredChannelColumns =
|
|
603
|
+
await storedChannelColumns(settingId);
|
|
604
|
+
|
|
605
|
+
if (columns.notificationChannels === null) {
|
|
606
|
+
expect(columns.notificationChannel).toBeNull();
|
|
607
|
+
} else {
|
|
608
|
+
const list: Array<string> =
|
|
609
|
+
columns.notificationChannels as Array<string>;
|
|
610
|
+
|
|
611
|
+
expect(list).toEqual(ComplianceRule.normaliseChannels(list));
|
|
612
|
+
expect(columns.notificationChannel).toBe(list[0] ?? null);
|
|
613
|
+
}
|
|
614
|
+
|
|
557
615
|
return {
|
|
558
616
|
ruleType: String(rows[0]["ruleType"]),
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
? null
|
|
562
|
-
: String(rows[0]["notificationChannel"]),
|
|
617
|
+
notificationChannels:
|
|
618
|
+
TeamComplianceSettingRules.getStoredChannels(columns),
|
|
563
619
|
enabled: rows[0]["enabled"] === true,
|
|
564
620
|
incidentSeverityIds: await joinRows(INCIDENT_JOIN_TABLE, settingId),
|
|
565
621
|
alertSeverityIds: await joinRows(ALERT_JOIN_TABLE, settingId),
|
|
@@ -676,6 +732,7 @@ describePostgres(
|
|
|
676
732
|
_id: true,
|
|
677
733
|
ruleType: true,
|
|
678
734
|
enabled: true,
|
|
735
|
+
notificationChannels: true,
|
|
679
736
|
notificationChannel: true,
|
|
680
737
|
incidentSeverities: {
|
|
681
738
|
_id: true,
|
|
@@ -792,13 +849,13 @@ describePostgres(
|
|
|
792
849
|
test("severity ids sent as strings land as join rows, and read back with their name, colour and order", async () => {
|
|
793
850
|
const id: ObjectID = await createRule({
|
|
794
851
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
795
|
-
|
|
852
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
796
853
|
incidentSeverities: asStrings([major, critical]),
|
|
797
854
|
});
|
|
798
855
|
|
|
799
856
|
expect(await stored(id)).toEqual({
|
|
800
857
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
801
|
-
|
|
858
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
802
859
|
enabled: true,
|
|
803
860
|
incidentSeverityIds: ids([critical, major]),
|
|
804
861
|
alertSeverityIds: [],
|
|
@@ -806,6 +863,10 @@ describePostgres(
|
|
|
806
863
|
|
|
807
864
|
const rule: TeamComplianceSetting | null = await readRule(id);
|
|
808
865
|
|
|
866
|
+
// The list the edit form loads, and the column older clients read.
|
|
867
|
+
expect(rule?.notificationChannels).toEqual([
|
|
868
|
+
ComplianceNotificationChannel.Call,
|
|
869
|
+
]);
|
|
809
870
|
expect(rule?.notificationChannel).toBe(
|
|
810
871
|
ComplianceNotificationChannel.Call,
|
|
811
872
|
);
|
|
@@ -829,13 +890,13 @@ describePostgres(
|
|
|
829
890
|
test("severity ids sent as {_id} JSON land as join rows", async () => {
|
|
830
891
|
const id: ObjectID = await createRule({
|
|
831
892
|
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
832
|
-
|
|
893
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
833
894
|
alertSeverities: asJson([criticalAlert]),
|
|
834
895
|
});
|
|
835
896
|
|
|
836
897
|
expect(await stored(id)).toEqual({
|
|
837
898
|
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
838
|
-
|
|
899
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
839
900
|
enabled: true,
|
|
840
901
|
incidentSeverityIds: [],
|
|
841
902
|
alertSeverityIds: ids([criticalAlert]),
|
|
@@ -858,7 +919,7 @@ describePostgres(
|
|
|
858
919
|
BaseModel.fromJSON<TeamComplianceSetting>(
|
|
859
920
|
{
|
|
860
921
|
ruleType: ComplianceRuleType.HasIncidentEpisodeOnCallRules,
|
|
861
|
-
|
|
922
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
862
923
|
enabled: true,
|
|
863
924
|
incidentSeverities: asJson([critical, minor]),
|
|
864
925
|
},
|
|
@@ -875,7 +936,7 @@ describePostgres(
|
|
|
875
936
|
|
|
876
937
|
expect(await stored(created.id!)).toEqual({
|
|
877
938
|
ruleType: ComplianceRuleType.HasIncidentEpisodeOnCallRules,
|
|
878
|
-
|
|
939
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
879
940
|
enabled: true,
|
|
880
941
|
incidentSeverityIds: ids([critical, minor]),
|
|
881
942
|
alertSeverityIds: [],
|
|
@@ -889,7 +950,7 @@ describePostgres(
|
|
|
889
950
|
|
|
890
951
|
expect(await stored(id)).toEqual({
|
|
891
952
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
892
|
-
|
|
953
|
+
notificationChannels: [],
|
|
893
954
|
enabled: true,
|
|
894
955
|
incidentSeverityIds: [],
|
|
895
956
|
alertSeverityIds: [],
|
|
@@ -898,20 +959,21 @@ describePostgres(
|
|
|
898
959
|
const rule: TeamComplianceSetting | null = await readRule(id);
|
|
899
960
|
|
|
900
961
|
expect(rule?.incidentSeverities || []).toEqual([]);
|
|
962
|
+
expect(rule?.notificationChannels ?? null).toBeNull();
|
|
901
963
|
expect(rule?.notificationChannel ?? null).toBeNull();
|
|
902
964
|
});
|
|
903
965
|
|
|
904
966
|
test("options the rule type does not use are not stored", async () => {
|
|
905
967
|
const methodRule: ObjectID = await createRule({
|
|
906
968
|
ruleType: ComplianceRuleType.HasNotificationCallMethod,
|
|
907
|
-
|
|
969
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
908
970
|
incidentSeverities: asStrings([critical]),
|
|
909
971
|
alertSeverities: asJson([criticalAlert]),
|
|
910
972
|
});
|
|
911
973
|
|
|
912
974
|
expect(await stored(methodRule)).toEqual({
|
|
913
975
|
ruleType: ComplianceRuleType.HasNotificationCallMethod,
|
|
914
|
-
|
|
976
|
+
notificationChannels: [],
|
|
915
977
|
enabled: true,
|
|
916
978
|
incidentSeverityIds: [],
|
|
917
979
|
alertSeverityIds: [],
|
|
@@ -919,14 +981,14 @@ describePostgres(
|
|
|
919
981
|
|
|
920
982
|
const incidentRule: ObjectID = await createRule({
|
|
921
983
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
922
|
-
|
|
984
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
923
985
|
incidentSeverities: asStrings([critical]),
|
|
924
986
|
alertSeverities: asJson([criticalAlert]),
|
|
925
987
|
});
|
|
926
988
|
|
|
927
989
|
expect(await stored(incidentRule)).toEqual({
|
|
928
990
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
929
|
-
|
|
991
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
930
992
|
enabled: true,
|
|
931
993
|
incidentSeverityIds: ids([critical]),
|
|
932
994
|
alertSeverityIds: [],
|
|
@@ -940,7 +1002,7 @@ describePostgres(
|
|
|
940
1002
|
|
|
941
1003
|
expect(await stored(alertRule)).toEqual({
|
|
942
1004
|
ruleType: ComplianceRuleType.HasAlertEpisodeOnCallRules,
|
|
943
|
-
|
|
1005
|
+
notificationChannels: [],
|
|
944
1006
|
enabled: true,
|
|
945
1007
|
incidentSeverityIds: [],
|
|
946
1008
|
alertSeverityIds: ids([warningAlert]),
|
|
@@ -950,7 +1012,7 @@ describePostgres(
|
|
|
950
1012
|
test("an exact duplicate is refused whatever the shape, order or case of its severity ids", async () => {
|
|
951
1013
|
await createRule({
|
|
952
1014
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
953
|
-
|
|
1015
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
954
1016
|
incidentSeverities: asStrings([critical, major]),
|
|
955
1017
|
});
|
|
956
1018
|
|
|
@@ -968,7 +1030,7 @@ describePostgres(
|
|
|
968
1030
|
await expect(
|
|
969
1031
|
createRule({
|
|
970
1032
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
971
|
-
|
|
1033
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
972
1034
|
incidentSeverities: incidentSeverities,
|
|
973
1035
|
}),
|
|
974
1036
|
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
@@ -985,7 +1047,7 @@ describePostgres(
|
|
|
985
1047
|
test("an upper-case id is stored as the lower-case uuid, and the lower-case spelling is then a duplicate", async () => {
|
|
986
1048
|
const id: ObjectID = await createRule({
|
|
987
1049
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
988
|
-
|
|
1050
|
+
notificationChannels: [ComplianceNotificationChannel.WhatsApp],
|
|
989
1051
|
incidentSeverities: [upper(minor)],
|
|
990
1052
|
});
|
|
991
1053
|
|
|
@@ -994,7 +1056,7 @@ describePostgres(
|
|
|
994
1056
|
await expect(
|
|
995
1057
|
createRule({
|
|
996
1058
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
997
|
-
|
|
1059
|
+
notificationChannels: [ComplianceNotificationChannel.WhatsApp],
|
|
998
1060
|
incidentSeverities: asStrings([minor]),
|
|
999
1061
|
}),
|
|
1000
1062
|
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
@@ -1008,7 +1070,7 @@ describePostgres(
|
|
|
1008
1070
|
await expect(
|
|
1009
1071
|
createRule({
|
|
1010
1072
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1011
|
-
|
|
1073
|
+
notificationChannels: [],
|
|
1012
1074
|
incidentSeverities: [],
|
|
1013
1075
|
}),
|
|
1014
1076
|
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
@@ -1021,7 +1083,7 @@ describePostgres(
|
|
|
1021
1083
|
await expect(
|
|
1022
1084
|
createRule({
|
|
1023
1085
|
ruleType: ComplianceRuleType.HasNotificationCallMethod,
|
|
1024
|
-
|
|
1086
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
1025
1087
|
incidentSeverities: asStrings([critical]),
|
|
1026
1088
|
}),
|
|
1027
1089
|
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
@@ -1034,7 +1096,7 @@ describePostgres(
|
|
|
1034
1096
|
|
|
1035
1097
|
await createRule({
|
|
1036
1098
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1037
|
-
|
|
1099
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1038
1100
|
incidentSeverities: asStrings(scope),
|
|
1039
1101
|
});
|
|
1040
1102
|
|
|
@@ -1042,7 +1104,7 @@ describePostgres(
|
|
|
1042
1104
|
// Push for the same severities.
|
|
1043
1105
|
{
|
|
1044
1106
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1045
|
-
|
|
1107
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1046
1108
|
incidentSeverities: asStrings(scope),
|
|
1047
1109
|
},
|
|
1048
1110
|
// Any channel for the same severities.
|
|
@@ -1053,30 +1115,30 @@ describePostgres(
|
|
|
1053
1115
|
// Call for a subset.
|
|
1054
1116
|
{
|
|
1055
1117
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1056
|
-
|
|
1118
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1057
1119
|
incidentSeverities: asStrings([critical]),
|
|
1058
1120
|
},
|
|
1059
1121
|
// Call for a superset.
|
|
1060
1122
|
{
|
|
1061
1123
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1062
|
-
|
|
1124
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1063
1125
|
incidentSeverities: asStrings([critical, major, minor]),
|
|
1064
1126
|
},
|
|
1065
1127
|
// Call for every severity.
|
|
1066
1128
|
{
|
|
1067
1129
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1068
|
-
|
|
1130
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1069
1131
|
},
|
|
1070
1132
|
// The episode rule type.
|
|
1071
1133
|
{
|
|
1072
1134
|
ruleType: ComplianceRuleType.HasIncidentEpisodeOnCallRules,
|
|
1073
|
-
|
|
1135
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1074
1136
|
incidentSeverities: asStrings(scope),
|
|
1075
1137
|
},
|
|
1076
1138
|
// The same rule on another team.
|
|
1077
1139
|
{
|
|
1078
1140
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1079
|
-
|
|
1141
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1080
1142
|
incidentSeverities: asStrings(scope),
|
|
1081
1143
|
teamId: otherTeamId,
|
|
1082
1144
|
},
|
|
@@ -1094,7 +1156,7 @@ describePostgres(
|
|
|
1094
1156
|
{
|
|
1095
1157
|
input: {
|
|
1096
1158
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1097
|
-
|
|
1159
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1098
1160
|
incidentSeverities: asStrings([otherProjectCritical]),
|
|
1099
1161
|
},
|
|
1100
1162
|
message: FOREIGN_SEVERITY_MESSAGE,
|
|
@@ -1102,7 +1164,7 @@ describePostgres(
|
|
|
1102
1164
|
{
|
|
1103
1165
|
input: {
|
|
1104
1166
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1105
|
-
|
|
1167
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1106
1168
|
incidentSeverities: asJson([critical, otherProjectCritical]),
|
|
1107
1169
|
},
|
|
1108
1170
|
message: FOREIGN_SEVERITY_MESSAGE,
|
|
@@ -1157,7 +1219,7 @@ describePostgres(
|
|
|
1157
1219
|
test("a repeated severity id (in any case, on create or update) is stored once", async () => {
|
|
1158
1220
|
const id: ObjectID = await createRule({
|
|
1159
1221
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1160
|
-
|
|
1222
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1161
1223
|
incidentSeverities: [critical.toString(), upper(critical)],
|
|
1162
1224
|
});
|
|
1163
1225
|
|
|
@@ -1198,7 +1260,7 @@ describePostgres(
|
|
|
1198
1260
|
test("a severity list item is checked by the id the save writes: one read by its `id` cannot smuggle in another project's severity", async () => {
|
|
1199
1261
|
const id: ObjectID = await createRule({
|
|
1200
1262
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1201
|
-
|
|
1263
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1202
1264
|
incidentSeverities: asStrings([critical]),
|
|
1203
1265
|
});
|
|
1204
1266
|
|
|
@@ -1220,7 +1282,7 @@ describePostgres(
|
|
|
1220
1282
|
await expect(
|
|
1221
1283
|
createRule({
|
|
1222
1284
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1223
|
-
|
|
1285
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1224
1286
|
incidentSeverities: [item as unknown as JSONObject],
|
|
1225
1287
|
}),
|
|
1226
1288
|
).rejects.toThrow(FOREIGN_SEVERITY_MESSAGE);
|
|
@@ -1238,7 +1300,7 @@ describePostgres(
|
|
|
1238
1300
|
|
|
1239
1301
|
expect(await stored(id)).toEqual({
|
|
1240
1302
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1241
|
-
|
|
1303
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1242
1304
|
enabled: true,
|
|
1243
1305
|
incidentSeverityIds: ids([critical]),
|
|
1244
1306
|
alertSeverityIds: [],
|
|
@@ -1261,7 +1323,7 @@ describePostgres(
|
|
|
1261
1323
|
await expect(
|
|
1262
1324
|
createRule({
|
|
1263
1325
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1264
|
-
|
|
1326
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1265
1327
|
incidentSeverities: asStrings([ObjectID.generate()]),
|
|
1266
1328
|
}),
|
|
1267
1329
|
).rejects.toThrow();
|
|
@@ -1284,7 +1346,7 @@ describePostgres(
|
|
|
1284
1346
|
async function callForCriticalAndMajor(): Promise<ObjectID> {
|
|
1285
1347
|
return await createRule({
|
|
1286
1348
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1287
|
-
|
|
1349
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1288
1350
|
incidentSeverities: asStrings([critical, major]),
|
|
1289
1351
|
});
|
|
1290
1352
|
}
|
|
@@ -1310,7 +1372,7 @@ describePostgres(
|
|
|
1310
1372
|
|
|
1311
1373
|
expect(await stored(id)).toEqual({
|
|
1312
1374
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1313
|
-
|
|
1375
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1314
1376
|
enabled: false,
|
|
1315
1377
|
incidentSeverityIds: ids([critical, major]),
|
|
1316
1378
|
alertSeverityIds: [],
|
|
@@ -1345,7 +1407,7 @@ describePostgres(
|
|
|
1345
1407
|
|
|
1346
1408
|
expect(await stored(id)).toEqual({
|
|
1347
1409
|
ruleType: ComplianceRuleType.HasNotificationCallMethod,
|
|
1348
|
-
|
|
1410
|
+
notificationChannels: [],
|
|
1349
1411
|
enabled: true,
|
|
1350
1412
|
incidentSeverityIds: [],
|
|
1351
1413
|
alertSeverityIds: [],
|
|
@@ -1354,6 +1416,7 @@ describePostgres(
|
|
|
1354
1416
|
const rule: TeamComplianceSetting | null = await readRule(id);
|
|
1355
1417
|
|
|
1356
1418
|
expect(rule?.incidentSeverities || []).toEqual([]);
|
|
1419
|
+
expect(rule?.notificationChannels).toEqual([]);
|
|
1357
1420
|
expect(rule?.notificationChannel ?? null).toBeNull();
|
|
1358
1421
|
});
|
|
1359
1422
|
|
|
@@ -1367,7 +1430,7 @@ describePostgres(
|
|
|
1367
1430
|
|
|
1368
1431
|
expect(await stored(id)).toEqual({
|
|
1369
1432
|
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
1370
|
-
|
|
1433
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1371
1434
|
enabled: true,
|
|
1372
1435
|
incidentSeverityIds: [],
|
|
1373
1436
|
alertSeverityIds: ids([criticalAlert]),
|
|
@@ -1393,7 +1456,7 @@ describePostgres(
|
|
|
1393
1456
|
|
|
1394
1457
|
expect(await stored(id)).toEqual({
|
|
1395
1458
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1396
|
-
|
|
1459
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1397
1460
|
enabled: true,
|
|
1398
1461
|
incidentSeverityIds: [],
|
|
1399
1462
|
alertSeverityIds: [],
|
|
@@ -1404,20 +1467,24 @@ describePostgres(
|
|
|
1404
1467
|
const id: ObjectID = await callForCriticalAndMajor();
|
|
1405
1468
|
|
|
1406
1469
|
await updateRule(id, {
|
|
1407
|
-
|
|
1470
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1408
1471
|
});
|
|
1409
1472
|
|
|
1410
1473
|
expect(await stored(id)).toEqual({
|
|
1411
1474
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1412
|
-
|
|
1475
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1413
1476
|
enabled: true,
|
|
1414
1477
|
incidentSeverityIds: ids([critical, major]),
|
|
1415
1478
|
alertSeverityIds: [],
|
|
1416
1479
|
});
|
|
1417
1480
|
|
|
1418
|
-
await updateRule(id, {
|
|
1481
|
+
await updateRule(id, { notificationChannels: [] });
|
|
1419
1482
|
|
|
1420
|
-
expect((await stored(id))?.
|
|
1483
|
+
expect((await stored(id))?.notificationChannels).toEqual([]);
|
|
1484
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1485
|
+
notificationChannels: [],
|
|
1486
|
+
notificationChannel: null,
|
|
1487
|
+
});
|
|
1421
1488
|
expect(await joinRows(INCIDENT_JOIN_TABLE, id)).toEqual(
|
|
1422
1489
|
ids([critical, major]),
|
|
1423
1490
|
);
|
|
@@ -1430,7 +1497,7 @@ describePostgres(
|
|
|
1430
1497
|
|
|
1431
1498
|
expect(await stored(id)).toEqual({
|
|
1432
1499
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1433
|
-
|
|
1500
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1434
1501
|
enabled: true,
|
|
1435
1502
|
incidentSeverityIds: ids([critical, major]),
|
|
1436
1503
|
alertSeverityIds: [],
|
|
@@ -1441,7 +1508,7 @@ describePostgres(
|
|
|
1441
1508
|
const id: ObjectID = await callForCriticalAndMajor();
|
|
1442
1509
|
|
|
1443
1510
|
await updateRule(id, {
|
|
1444
|
-
|
|
1511
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1445
1512
|
incidentSeverities: asJson([major, critical]),
|
|
1446
1513
|
});
|
|
1447
1514
|
|
|
@@ -1455,7 +1522,7 @@ describePostgres(
|
|
|
1455
1522
|
|
|
1456
1523
|
await createRule({
|
|
1457
1524
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1458
|
-
|
|
1525
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1459
1526
|
incidentSeverities: asStrings([critical]),
|
|
1460
1527
|
});
|
|
1461
1528
|
|
|
@@ -1475,7 +1542,7 @@ describePostgres(
|
|
|
1475
1542
|
|
|
1476
1543
|
expect(await stored(id)).toEqual({
|
|
1477
1544
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1478
|
-
|
|
1545
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1479
1546
|
enabled: true,
|
|
1480
1547
|
incidentSeverityIds: ids([critical, major]),
|
|
1481
1548
|
alertSeverityIds: [],
|
|
@@ -1483,141 +1550,884 @@ describePostgres(
|
|
|
1483
1550
|
});
|
|
1484
1551
|
});
|
|
1485
1552
|
|
|
1486
|
-
describe("
|
|
1487
|
-
test("
|
|
1553
|
+
describe("a rule on several channels", () => {
|
|
1554
|
+
test("stores them as one jsonb list in catalog order, with the first in the older column, and reads them back as a list", async () => {
|
|
1488
1555
|
const id: ObjectID = await createRule({
|
|
1489
1556
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1557
|
+
// Picked out of order, and one twice.
|
|
1558
|
+
notificationChannels: [
|
|
1559
|
+
ComplianceNotificationChannel.Push,
|
|
1560
|
+
ComplianceNotificationChannel.Call,
|
|
1561
|
+
ComplianceNotificationChannel.Push,
|
|
1562
|
+
],
|
|
1563
|
+
incidentSeverities: asStrings([critical]),
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1566
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1567
|
+
notificationChannels: [
|
|
1568
|
+
ComplianceNotificationChannel.Call,
|
|
1569
|
+
ComplianceNotificationChannel.Push,
|
|
1570
|
+
],
|
|
1490
1571
|
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1491
|
-
incidentSeverities: asStrings([critical, major]),
|
|
1492
1572
|
});
|
|
1493
1573
|
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1574
|
+
const rule: TeamComplianceSetting | null = await readRule(id);
|
|
1575
|
+
|
|
1576
|
+
expect(rule?.notificationChannels).toEqual([
|
|
1577
|
+
ComplianceNotificationChannel.Call,
|
|
1578
|
+
ComplianceNotificationChannel.Push,
|
|
1579
|
+
]);
|
|
1580
|
+
expect(rule?.notificationChannel).toBe(
|
|
1581
|
+
ComplianceNotificationChannel.Call,
|
|
1498
1582
|
);
|
|
1583
|
+
});
|
|
1499
1584
|
|
|
1500
|
-
|
|
1585
|
+
test("duplicates compare the channels, not the order they were picked in", async () => {
|
|
1586
|
+
await createRule({
|
|
1501
1587
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1588
|
+
notificationChannels: [
|
|
1589
|
+
ComplianceNotificationChannel.Call,
|
|
1590
|
+
ComplianceNotificationChannel.Push,
|
|
1591
|
+
],
|
|
1592
|
+
incidentSeverities: asStrings([critical]),
|
|
1506
1593
|
});
|
|
1507
1594
|
|
|
1508
|
-
|
|
1595
|
+
await expect(
|
|
1596
|
+
createRule({
|
|
1597
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1598
|
+
notificationChannels: [
|
|
1599
|
+
ComplianceNotificationChannel.Push,
|
|
1600
|
+
ComplianceNotificationChannel.Call,
|
|
1601
|
+
ComplianceNotificationChannel.Call,
|
|
1602
|
+
],
|
|
1603
|
+
incidentSeverities: asStrings([critical]),
|
|
1604
|
+
}),
|
|
1605
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
1509
1606
|
|
|
1510
|
-
|
|
1607
|
+
// Fewer channels, more channels or other severities check other things.
|
|
1608
|
+
for (const input of [
|
|
1511
1609
|
{
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
color: "#FFA500",
|
|
1515
|
-
order: 2,
|
|
1610
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1611
|
+
incidentSeverities: asStrings([critical]),
|
|
1516
1612
|
},
|
|
1517
|
-
|
|
1613
|
+
{
|
|
1614
|
+
notificationChannels: [
|
|
1615
|
+
ComplianceNotificationChannel.SMS,
|
|
1616
|
+
ComplianceNotificationChannel.Push,
|
|
1617
|
+
ComplianceNotificationChannel.Call,
|
|
1618
|
+
],
|
|
1619
|
+
incidentSeverities: asStrings([critical]),
|
|
1620
|
+
},
|
|
1621
|
+
{
|
|
1622
|
+
notificationChannels: [
|
|
1623
|
+
ComplianceNotificationChannel.Call,
|
|
1624
|
+
ComplianceNotificationChannel.Push,
|
|
1625
|
+
],
|
|
1626
|
+
incidentSeverities: asStrings([major]),
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
notificationChannels: [],
|
|
1630
|
+
incidentSeverities: asStrings([critical]),
|
|
1631
|
+
},
|
|
1632
|
+
]) {
|
|
1633
|
+
await createRule({
|
|
1634
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1635
|
+
...input,
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
expect(await countRules()).toBe(5);
|
|
1518
1640
|
});
|
|
1519
1641
|
|
|
1520
|
-
test("
|
|
1642
|
+
test("an update adds, removes and clears channels, keeping both columns in step and the severities alone", async () => {
|
|
1521
1643
|
const id: ObjectID = await createRule({
|
|
1522
|
-
ruleType: ComplianceRuleType.
|
|
1523
|
-
|
|
1524
|
-
|
|
1644
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1645
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
1646
|
+
incidentSeverities: asStrings([critical, major]),
|
|
1525
1647
|
});
|
|
1526
1648
|
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1649
|
+
const steps: Array<[unknown, StoredChannelColumns]> = [
|
|
1650
|
+
[
|
|
1651
|
+
[
|
|
1652
|
+
ComplianceNotificationChannel.SMS,
|
|
1653
|
+
ComplianceNotificationChannel.Call,
|
|
1654
|
+
],
|
|
1655
|
+
{
|
|
1656
|
+
notificationChannels: [
|
|
1657
|
+
ComplianceNotificationChannel.Call,
|
|
1658
|
+
ComplianceNotificationChannel.SMS,
|
|
1659
|
+
],
|
|
1660
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1661
|
+
},
|
|
1662
|
+
],
|
|
1663
|
+
[
|
|
1664
|
+
[ComplianceNotificationChannel.Telegram],
|
|
1665
|
+
{
|
|
1666
|
+
notificationChannels: [ComplianceNotificationChannel.Telegram],
|
|
1667
|
+
notificationChannel: ComplianceNotificationChannel.Telegram,
|
|
1668
|
+
},
|
|
1669
|
+
],
|
|
1670
|
+
// Null is "any channel", as an empty list is.
|
|
1671
|
+
[null, { notificationChannels: [], notificationChannel: null }],
|
|
1672
|
+
[
|
|
1673
|
+
[ComplianceNotificationChannel.Webhook],
|
|
1674
|
+
{
|
|
1675
|
+
notificationChannels: [ComplianceNotificationChannel.Webhook],
|
|
1676
|
+
notificationChannel: ComplianceNotificationChannel.Webhook,
|
|
1677
|
+
},
|
|
1678
|
+
],
|
|
1679
|
+
[[], { notificationChannels: [], notificationChannel: null }],
|
|
1680
|
+
];
|
|
1531
1681
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1682
|
+
for (const [sent, expected] of steps) {
|
|
1683
|
+
await updateRule(id, { notificationChannels: sent as JSONObject[] });
|
|
1684
|
+
|
|
1685
|
+
expect(await storedChannelColumns(id)).toEqual(expected);
|
|
1686
|
+
expect(await joinRows(INCIDENT_JOIN_TABLE, id)).toEqual(
|
|
1687
|
+
ids([critical, major]),
|
|
1688
|
+
);
|
|
1689
|
+
}
|
|
1535
1690
|
});
|
|
1536
1691
|
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
* services - the only way the product deletes a severity - a rule the
|
|
1540
|
-
* cascade leaves with no severity is paused rather than left to read
|
|
1541
|
-
* as a rule for every severity.
|
|
1542
|
-
*/
|
|
1543
|
-
test("deleting a rule's only severity through the service pauses the rule; a rule with another severity left keeps it", async () => {
|
|
1544
|
-
const onlyCritical: ObjectID = await createRule({
|
|
1692
|
+
test("re-saving a rule's own channels is no duplicate; taking a sibling's is refused and changes nothing", async () => {
|
|
1693
|
+
const callAndPush: ObjectID = await createRule({
|
|
1545
1694
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
ruleType: ComplianceRuleType.HasIncidentEpisodeOnCallRules,
|
|
1551
|
-
notificationChannel: ComplianceNotificationChannel.SMS,
|
|
1695
|
+
notificationChannels: [
|
|
1696
|
+
ComplianceNotificationChannel.Call,
|
|
1697
|
+
ComplianceNotificationChannel.Push,
|
|
1698
|
+
],
|
|
1552
1699
|
incidentSeverities: asStrings([critical]),
|
|
1553
1700
|
});
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
notificationChannel: ComplianceNotificationChannel.Push,
|
|
1557
|
-
incidentSeverities: asStrings([critical, major]),
|
|
1558
|
-
});
|
|
1559
|
-
const everySeverity: ObjectID = await createRule({
|
|
1701
|
+
|
|
1702
|
+
const callOnly: ObjectID = await createRule({
|
|
1560
1703
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
const alertRule: ObjectID = await createRule({
|
|
1564
|
-
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
1565
|
-
alertSeverities: asStrings([criticalAlert]),
|
|
1704
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1705
|
+
incidentSeverities: asStrings([critical]),
|
|
1566
1706
|
});
|
|
1567
1707
|
|
|
1568
|
-
await
|
|
1569
|
-
|
|
1570
|
-
|
|
1708
|
+
await updateRule(callAndPush, {
|
|
1709
|
+
notificationChannels: [
|
|
1710
|
+
ComplianceNotificationChannel.Push,
|
|
1711
|
+
ComplianceNotificationChannel.Call,
|
|
1712
|
+
],
|
|
1713
|
+
incidentSeverities: asJson([critical]),
|
|
1571
1714
|
});
|
|
1572
1715
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1716
|
+
await expect(
|
|
1717
|
+
updateRule(callOnly, {
|
|
1718
|
+
notificationChannels: [
|
|
1719
|
+
ComplianceNotificationChannel.Push,
|
|
1720
|
+
ComplianceNotificationChannel.Call,
|
|
1721
|
+
],
|
|
1722
|
+
}),
|
|
1723
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
1724
|
+
|
|
1725
|
+
expect(await storedChannelColumns(callOnly)).toEqual({
|
|
1726
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1575
1727
|
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1576
|
-
enabled: false,
|
|
1577
|
-
incidentSeverityIds: [],
|
|
1578
|
-
alertSeverityIds: [],
|
|
1579
1728
|
});
|
|
1580
|
-
|
|
1581
|
-
expect((await stored(episodeOnlyCritical))?.enabled).toBe(false);
|
|
1582
|
-
expect(await storedOptions(episodeOnlyCritical)).toEqual(MARKED);
|
|
1583
|
-
expect(await storedOptions(criticalAndMajor)).toBeNull();
|
|
1584
|
-
expect(await storedOptions(everySeverity)).toBeNull();
|
|
1729
|
+
});
|
|
1585
1730
|
|
|
1586
|
-
|
|
1731
|
+
test("anything but a list of channels this build knows is refused, and nothing is written", async () => {
|
|
1732
|
+
const id: ObjectID = await createRule({
|
|
1587
1733
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
incidentSeverityIds: ids([major]),
|
|
1591
|
-
alertSeverityIds: [],
|
|
1734
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1735
|
+
incidentSeverities: asStrings([critical]),
|
|
1592
1736
|
});
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1737
|
+
|
|
1738
|
+
const refused: Array<[unknown, string]> = [
|
|
1739
|
+
[
|
|
1740
|
+
ComplianceNotificationChannel.Push,
|
|
1741
|
+
"The notification channels of a compliance rule must be a list of channels.",
|
|
1742
|
+
],
|
|
1743
|
+
[
|
|
1744
|
+
{ channel: ComplianceNotificationChannel.Push },
|
|
1745
|
+
"The notification channels of a compliance rule must be a list of channels.",
|
|
1746
|
+
],
|
|
1747
|
+
[
|
|
1748
|
+
[ComplianceNotificationChannel.Push, "Pager"],
|
|
1749
|
+
'"Pager" is not a notification channel a compliance rule can require.',
|
|
1750
|
+
],
|
|
1751
|
+
[
|
|
1752
|
+
[ComplianceNotificationChannel.Push.toLowerCase()],
|
|
1753
|
+
'"push" is not a notification channel a compliance rule can require.',
|
|
1754
|
+
],
|
|
1755
|
+
];
|
|
1756
|
+
|
|
1757
|
+
for (const [sent, message] of refused) {
|
|
1758
|
+
await expect(
|
|
1759
|
+
createRule({
|
|
1760
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1761
|
+
notificationChannels:
|
|
1762
|
+
sent as Array<ComplianceNotificationChannel>,
|
|
1763
|
+
incidentSeverities: asStrings([major]),
|
|
1764
|
+
}),
|
|
1765
|
+
).rejects.toThrow(message);
|
|
1766
|
+
|
|
1767
|
+
await expect(
|
|
1768
|
+
updateRule(id, { notificationChannels: sent as JSONObject }),
|
|
1769
|
+
).rejects.toThrow(message);
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
expect(await countRules()).toBe(1);
|
|
1773
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1774
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1775
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1597
1776
|
});
|
|
1598
1777
|
});
|
|
1599
1778
|
|
|
1600
|
-
test("
|
|
1601
|
-
const
|
|
1602
|
-
ruleType: ComplianceRuleType.
|
|
1603
|
-
|
|
1604
|
-
|
|
1779
|
+
test("a method rule stores no channels, whichever column they arrive in", async () => {
|
|
1780
|
+
const fromList: ObjectID = await createRule({
|
|
1781
|
+
ruleType: ComplianceRuleType.HasNotificationSMSMethod,
|
|
1782
|
+
notificationChannels: [
|
|
1783
|
+
ComplianceNotificationChannel.Call,
|
|
1784
|
+
ComplianceNotificationChannel.Push,
|
|
1785
|
+
],
|
|
1605
1786
|
});
|
|
1606
|
-
const
|
|
1607
|
-
ruleType: ComplianceRuleType.
|
|
1608
|
-
|
|
1787
|
+
const fromSingle: ObjectID = await createRule({
|
|
1788
|
+
ruleType: ComplianceRuleType.HasNotificationPushMethod,
|
|
1789
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1609
1790
|
});
|
|
1610
1791
|
|
|
1611
|
-
|
|
1612
|
-
id
|
|
1613
|
-
|
|
1792
|
+
for (const id of [fromList, fromSingle]) {
|
|
1793
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1794
|
+
notificationChannels: [],
|
|
1795
|
+
notificationChannel: null,
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1798
|
+
});
|
|
1799
|
+
|
|
1800
|
+
test("changing a multi-channel rule into a method rule clears both columns", async () => {
|
|
1801
|
+
const id: ObjectID = await createRule({
|
|
1802
|
+
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
1803
|
+
notificationChannels: [
|
|
1804
|
+
ComplianceNotificationChannel.Push,
|
|
1805
|
+
ComplianceNotificationChannel.SMS,
|
|
1806
|
+
],
|
|
1807
|
+
alertSeverities: asStrings([criticalAlert]),
|
|
1614
1808
|
});
|
|
1615
1809
|
|
|
1616
|
-
|
|
1617
|
-
|
|
1810
|
+
await updateRule(id, {
|
|
1811
|
+
ruleType: ComplianceRuleType.HasNotificationWhatsAppMethod,
|
|
1812
|
+
});
|
|
1813
|
+
|
|
1814
|
+
expect(await stored(id)).toEqual({
|
|
1815
|
+
ruleType: ComplianceRuleType.HasNotificationWhatsAppMethod,
|
|
1816
|
+
notificationChannels: [],
|
|
1817
|
+
enabled: true,
|
|
1818
|
+
incidentSeverityIds: [],
|
|
1618
1819
|
alertSeverityIds: [],
|
|
1619
1820
|
});
|
|
1620
|
-
expect(
|
|
1821
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1822
|
+
notificationChannels: [],
|
|
1823
|
+
notificationChannel: null,
|
|
1824
|
+
});
|
|
1825
|
+
});
|
|
1826
|
+
});
|
|
1827
|
+
|
|
1828
|
+
/*
|
|
1829
|
+
* API clients written before a rule could hold several channels, and a
|
|
1830
|
+
* Dashboard bundle cached from before the upgrade, send the single
|
|
1831
|
+
* `notificationChannel`. They must keep getting the rule they asked for -
|
|
1832
|
+
* a channel dropped on the floor would turn "Call for Critical" into
|
|
1833
|
+
* "any channel for Critical".
|
|
1834
|
+
*/
|
|
1835
|
+
describe("a client that only knows notificationChannel", () => {
|
|
1836
|
+
test("a create that sends the single column gets exactly that channel, as a one-item list", async () => {
|
|
1837
|
+
const id: ObjectID = await createRule({
|
|
1838
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1839
|
+
notificationChannel: ComplianceNotificationChannel.SMS,
|
|
1840
|
+
incidentSeverities: asStrings([critical]),
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1843
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1844
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
1845
|
+
notificationChannel: ComplianceNotificationChannel.SMS,
|
|
1846
|
+
});
|
|
1847
|
+
expect((await readRule(id))?.notificationChannels).toEqual([
|
|
1848
|
+
ComplianceNotificationChannel.SMS,
|
|
1849
|
+
]);
|
|
1850
|
+
|
|
1851
|
+
// It is the rule a list client would have made.
|
|
1852
|
+
await expect(
|
|
1853
|
+
createRule({
|
|
1854
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1855
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
1856
|
+
incidentSeverities: asStrings([critical]),
|
|
1857
|
+
}),
|
|
1858
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
1859
|
+
});
|
|
1860
|
+
|
|
1861
|
+
test("an update that sends the single column replaces the whole list; null clears it", async () => {
|
|
1862
|
+
const id: ObjectID = await createRule({
|
|
1863
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1864
|
+
notificationChannels: [
|
|
1865
|
+
ComplianceNotificationChannel.Call,
|
|
1866
|
+
ComplianceNotificationChannel.Push,
|
|
1867
|
+
],
|
|
1868
|
+
incidentSeverities: asStrings([critical]),
|
|
1869
|
+
});
|
|
1870
|
+
|
|
1871
|
+
await updateRule(id, {
|
|
1872
|
+
notificationChannel: ComplianceNotificationChannel.WhatsApp,
|
|
1873
|
+
});
|
|
1874
|
+
|
|
1875
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1876
|
+
notificationChannels: [ComplianceNotificationChannel.WhatsApp],
|
|
1877
|
+
notificationChannel: ComplianceNotificationChannel.WhatsApp,
|
|
1878
|
+
});
|
|
1879
|
+
|
|
1880
|
+
await updateRule(id, { notificationChannel: null });
|
|
1881
|
+
|
|
1882
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1883
|
+
notificationChannels: [],
|
|
1884
|
+
notificationChannel: null,
|
|
1885
|
+
});
|
|
1886
|
+
expect(await joinRows(INCIDENT_JOIN_TABLE, id)).toEqual(
|
|
1887
|
+
ids([critical]),
|
|
1888
|
+
);
|
|
1889
|
+
});
|
|
1890
|
+
|
|
1891
|
+
test("a client that sends both is taken at its list, whatever stale single channel rides along", async () => {
|
|
1892
|
+
const id: ObjectID = await createRule({
|
|
1893
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1894
|
+
notificationChannels: [
|
|
1895
|
+
ComplianceNotificationChannel.Call,
|
|
1896
|
+
ComplianceNotificationChannel.Push,
|
|
1897
|
+
],
|
|
1898
|
+
incidentSeverities: asStrings([critical]),
|
|
1899
|
+
});
|
|
1900
|
+
|
|
1901
|
+
// Read the rule, change the list, send both back.
|
|
1902
|
+
await updateRule(id, {
|
|
1903
|
+
notificationChannels: [ComplianceNotificationChannel.Email],
|
|
1904
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1905
|
+
});
|
|
1906
|
+
|
|
1907
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1908
|
+
notificationChannels: [ComplianceNotificationChannel.Email],
|
|
1909
|
+
notificationChannel: ComplianceNotificationChannel.Email,
|
|
1910
|
+
});
|
|
1911
|
+
});
|
|
1912
|
+
|
|
1913
|
+
test("a single channel this build does not know is refused, even beside a valid list", async () => {
|
|
1914
|
+
const id: ObjectID = await createRule({
|
|
1915
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1916
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1917
|
+
});
|
|
1918
|
+
|
|
1919
|
+
await expect(
|
|
1920
|
+
updateRule(id, {
|
|
1921
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1922
|
+
notificationChannel: "Pager",
|
|
1923
|
+
}),
|
|
1924
|
+
).rejects.toThrow(
|
|
1925
|
+
'"Pager" is not a notification channel a compliance rule can require.',
|
|
1926
|
+
);
|
|
1927
|
+
|
|
1928
|
+
await expect(
|
|
1929
|
+
createRule({
|
|
1930
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1931
|
+
notificationChannel: "Pager" as ComplianceNotificationChannel,
|
|
1932
|
+
incidentSeverities: asStrings([major]),
|
|
1933
|
+
}),
|
|
1934
|
+
).rejects.toThrow(
|
|
1935
|
+
'"Pager" is not a notification channel a compliance rule can require.',
|
|
1936
|
+
);
|
|
1937
|
+
|
|
1938
|
+
expect(await countRules()).toBe(1);
|
|
1939
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
1940
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1941
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1942
|
+
});
|
|
1943
|
+
});
|
|
1944
|
+
});
|
|
1945
|
+
|
|
1946
|
+
/*
|
|
1947
|
+
* A replica of the previous build keeps serving while this one rolls
|
|
1948
|
+
* out (and runs again after a downgrade). It reads and writes only
|
|
1949
|
+
* notificationChannel and never touches the list - so a row it created
|
|
1950
|
+
* has no list, and a row it re-channelled has a list its single column
|
|
1951
|
+
* no longer agrees with. Either way the single column is what the admin
|
|
1952
|
+
* last asked for, and the duplicate check must compare against that.
|
|
1953
|
+
*/
|
|
1954
|
+
describe("a row an older build wrote", () => {
|
|
1955
|
+
async function insertRawRule(data: {
|
|
1956
|
+
notificationChannels: Array<string> | null;
|
|
1957
|
+
notificationChannel: string | null;
|
|
1958
|
+
severities: Array<ObjectID>;
|
|
1959
|
+
}): Promise<ObjectID> {
|
|
1960
|
+
const id: ObjectID = ObjectID.generate();
|
|
1961
|
+
|
|
1962
|
+
await insert("TeamComplianceSetting", {
|
|
1963
|
+
_id: id.toString(),
|
|
1964
|
+
projectId: projectId.toString(),
|
|
1965
|
+
teamId: teamId.toString(),
|
|
1966
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1967
|
+
enabled: true,
|
|
1968
|
+
notificationChannel: data.notificationChannel,
|
|
1969
|
+
// jsonb is bound as its JSON text.
|
|
1970
|
+
notificationChannels:
|
|
1971
|
+
data.notificationChannels === null
|
|
1972
|
+
? null
|
|
1973
|
+
: JSON.stringify(data.notificationChannels),
|
|
1974
|
+
version: 1,
|
|
1975
|
+
});
|
|
1976
|
+
|
|
1977
|
+
for (const severity of data.severities) {
|
|
1978
|
+
await insert(INCIDENT_JOIN_TABLE, {
|
|
1979
|
+
teamComplianceSettingId: id.toString(),
|
|
1980
|
+
incidentSeverityId: severity.toString(),
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
return id;
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
test("a rule it created, with no list, is compared by its single column", async () => {
|
|
1988
|
+
const legacy: ObjectID = await insertRawRule({
|
|
1989
|
+
notificationChannels: null,
|
|
1990
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
1991
|
+
severities: [critical],
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
expect(
|
|
1995
|
+
TeamComplianceSettingRules.getStoredChannels(
|
|
1996
|
+
await storedChannelColumns(legacy),
|
|
1997
|
+
),
|
|
1998
|
+
).toEqual([ComplianceNotificationChannel.Call]);
|
|
1999
|
+
|
|
2000
|
+
await expect(
|
|
2001
|
+
createRule({
|
|
2002
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2003
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2004
|
+
incidentSeverities: asStrings([critical]),
|
|
2005
|
+
}),
|
|
2006
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
2007
|
+
|
|
2008
|
+
await createRule({
|
|
2009
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2010
|
+
notificationChannels: [
|
|
2011
|
+
ComplianceNotificationChannel.Call,
|
|
2012
|
+
ComplianceNotificationChannel.Push,
|
|
2013
|
+
],
|
|
2014
|
+
incidentSeverities: asStrings([critical]),
|
|
2015
|
+
});
|
|
2016
|
+
|
|
2017
|
+
expect(await countRules()).toBe(2);
|
|
2018
|
+
});
|
|
2019
|
+
|
|
2020
|
+
test("a rule it re-channelled - its single column no longer agreeing with the list - checks the single column", async () => {
|
|
2021
|
+
const id: ObjectID = await createRule({
|
|
2022
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2023
|
+
notificationChannels: [
|
|
2024
|
+
ComplianceNotificationChannel.Call,
|
|
2025
|
+
ComplianceNotificationChannel.Push,
|
|
2026
|
+
],
|
|
2027
|
+
incidentSeverities: asStrings([critical]),
|
|
2028
|
+
});
|
|
2029
|
+
|
|
2030
|
+
await database.query(
|
|
2031
|
+
`UPDATE "${schema}"."TeamComplianceSetting" SET "notificationChannel" = 'SMS' WHERE "_id" = $1`,
|
|
2032
|
+
[id.toString()],
|
|
2033
|
+
);
|
|
2034
|
+
|
|
2035
|
+
await expect(
|
|
2036
|
+
createRule({
|
|
2037
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2038
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
2039
|
+
incidentSeverities: asStrings([critical]),
|
|
2040
|
+
}),
|
|
2041
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
2042
|
+
|
|
2043
|
+
// The Call-and-Push rule it replaced is no longer on the team.
|
|
2044
|
+
await createRule({
|
|
2045
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2046
|
+
notificationChannels: [
|
|
2047
|
+
ComplianceNotificationChannel.Push,
|
|
2048
|
+
ComplianceNotificationChannel.Call,
|
|
2049
|
+
],
|
|
2050
|
+
incidentSeverities: asStrings([critical]),
|
|
2051
|
+
});
|
|
2052
|
+
|
|
2053
|
+
// Saved again by this build, the pair is back in step.
|
|
2054
|
+
await updateRule(id, {
|
|
2055
|
+
notificationChannels: [
|
|
2056
|
+
ComplianceNotificationChannel.SMS,
|
|
2057
|
+
ComplianceNotificationChannel.Email,
|
|
2058
|
+
],
|
|
2059
|
+
});
|
|
2060
|
+
|
|
2061
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
2062
|
+
notificationChannels: [
|
|
2063
|
+
ComplianceNotificationChannel.SMS,
|
|
2064
|
+
ComplianceNotificationChannel.Email,
|
|
2065
|
+
],
|
|
2066
|
+
notificationChannel: ComplianceNotificationChannel.SMS,
|
|
2067
|
+
});
|
|
2068
|
+
});
|
|
2069
|
+
|
|
2070
|
+
test("a rule it cleared to any channel no longer checks the list it had", async () => {
|
|
2071
|
+
const id: ObjectID = await createRule({
|
|
2072
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2073
|
+
notificationChannels: [
|
|
2074
|
+
ComplianceNotificationChannel.Call,
|
|
2075
|
+
ComplianceNotificationChannel.Push,
|
|
2076
|
+
],
|
|
2077
|
+
incidentSeverities: asStrings([critical]),
|
|
2078
|
+
});
|
|
2079
|
+
|
|
2080
|
+
await database.query(
|
|
2081
|
+
`UPDATE "${schema}"."TeamComplianceSetting" SET "notificationChannel" = NULL WHERE "_id" = $1`,
|
|
2082
|
+
[id.toString()],
|
|
2083
|
+
);
|
|
2084
|
+
|
|
2085
|
+
await expect(
|
|
2086
|
+
createRule({
|
|
2087
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2088
|
+
notificationChannels: [],
|
|
2089
|
+
incidentSeverities: asStrings([critical]),
|
|
2090
|
+
}),
|
|
2091
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
2092
|
+
});
|
|
2093
|
+
|
|
2094
|
+
test("a rule it re-saved without changing the channel keeps every channel of its list", async () => {
|
|
2095
|
+
const id: ObjectID = await createRule({
|
|
2096
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2097
|
+
notificationChannels: [
|
|
2098
|
+
ComplianceNotificationChannel.Call,
|
|
2099
|
+
ComplianceNotificationChannel.Push,
|
|
2100
|
+
],
|
|
2101
|
+
incidentSeverities: asStrings([critical]),
|
|
2102
|
+
});
|
|
2103
|
+
|
|
2104
|
+
// What the older form shows - and saves back - is the first channel.
|
|
2105
|
+
await database.query(
|
|
2106
|
+
`UPDATE "${schema}"."TeamComplianceSetting" SET "notificationChannel" = 'Call' WHERE "_id" = $1`,
|
|
2107
|
+
[id.toString()],
|
|
2108
|
+
);
|
|
2109
|
+
|
|
2110
|
+
await expect(
|
|
2111
|
+
createRule({
|
|
2112
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2113
|
+
notificationChannels: [
|
|
2114
|
+
ComplianceNotificationChannel.Push,
|
|
2115
|
+
ComplianceNotificationChannel.Call,
|
|
2116
|
+
],
|
|
2117
|
+
incidentSeverities: asStrings([critical]),
|
|
2118
|
+
}),
|
|
2119
|
+
).rejects.toThrow(DUPLICATE_COMPLIANCE_RULE_MESSAGE);
|
|
2120
|
+
});
|
|
2121
|
+
});
|
|
2122
|
+
|
|
2123
|
+
describe("the migration that added the list", () => {
|
|
2124
|
+
// up()'s statements, in order, without running them.
|
|
2125
|
+
async function migrationStatements(): Promise<Array<string>> {
|
|
2126
|
+
const statements: Array<string> = [];
|
|
2127
|
+
|
|
2128
|
+
await new AddTeamComplianceRuleNotificationChannels1796500000000().up({
|
|
2129
|
+
query: (statement: string): Promise<void> => {
|
|
2130
|
+
statements.push(statement);
|
|
2131
|
+
return Promise.resolve();
|
|
2132
|
+
},
|
|
2133
|
+
} as unknown as QueryRunner);
|
|
2134
|
+
|
|
2135
|
+
return statements;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
test("added it to the migrated table as nullable jsonb with no default", async () => {
|
|
2139
|
+
const columns: Array<SqlRow> = await database.query(
|
|
2140
|
+
`SELECT data_type, is_nullable, column_default
|
|
2141
|
+
FROM information_schema.columns
|
|
2142
|
+
WHERE table_schema = 'public' AND table_name = 'TeamComplianceSetting' AND column_name = 'notificationChannels'`,
|
|
2143
|
+
);
|
|
2144
|
+
|
|
2145
|
+
expect(columns).toEqual([
|
|
2146
|
+
{ data_type: "jsonb", is_nullable: "YES", column_default: null },
|
|
2147
|
+
]);
|
|
2148
|
+
});
|
|
2149
|
+
|
|
2150
|
+
test("its backfill gives every rule with a channel that channel as a list, and touches nothing else", async () => {
|
|
2151
|
+
const statements: Array<string> = await migrationStatements();
|
|
2152
|
+
const backfill: string = statements[1]!;
|
|
2153
|
+
|
|
2154
|
+
expect(backfill.startsWith('UPDATE "TeamComplianceSetting" SET')).toBe(
|
|
2155
|
+
true,
|
|
2156
|
+
);
|
|
2157
|
+
|
|
2158
|
+
/*
|
|
2159
|
+
* Rows as the previous build left them, one written since - and
|
|
2160
|
+
* rules of every kind. Run against this suite's own table, never
|
|
2161
|
+
* the migrated one.
|
|
2162
|
+
*/
|
|
2163
|
+
const rows: Array<[string, SqlRow]> = [
|
|
2164
|
+
[
|
|
2165
|
+
"call rule",
|
|
2166
|
+
{
|
|
2167
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2168
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
2169
|
+
notificationChannels: null,
|
|
2170
|
+
},
|
|
2171
|
+
],
|
|
2172
|
+
[
|
|
2173
|
+
"telegram alert episode rule",
|
|
2174
|
+
{
|
|
2175
|
+
ruleType: ComplianceRuleType.HasAlertEpisodeOnCallRules,
|
|
2176
|
+
notificationChannel: ComplianceNotificationChannel.Telegram,
|
|
2177
|
+
notificationChannels: null,
|
|
2178
|
+
},
|
|
2179
|
+
],
|
|
2180
|
+
[
|
|
2181
|
+
"any-channel rule",
|
|
2182
|
+
{
|
|
2183
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2184
|
+
notificationChannel: null,
|
|
2185
|
+
notificationChannels: null,
|
|
2186
|
+
},
|
|
2187
|
+
],
|
|
2188
|
+
[
|
|
2189
|
+
"method rule",
|
|
2190
|
+
{
|
|
2191
|
+
ruleType: ComplianceRuleType.HasNotificationEmailMethod,
|
|
2192
|
+
notificationChannel: null,
|
|
2193
|
+
notificationChannels: null,
|
|
2194
|
+
},
|
|
2195
|
+
],
|
|
2196
|
+
[
|
|
2197
|
+
"rule already on a list",
|
|
2198
|
+
{
|
|
2199
|
+
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
2200
|
+
notificationChannel: ComplianceNotificationChannel.Push,
|
|
2201
|
+
notificationChannels: JSON.stringify([
|
|
2202
|
+
ComplianceNotificationChannel.Push,
|
|
2203
|
+
ComplianceNotificationChannel.SMS,
|
|
2204
|
+
]),
|
|
2205
|
+
},
|
|
2206
|
+
],
|
|
2207
|
+
];
|
|
2208
|
+
|
|
2209
|
+
const idsByName: Map<string, ObjectID> = new Map<string, ObjectID>();
|
|
2210
|
+
|
|
2211
|
+
for (const [name, row] of rows) {
|
|
2212
|
+
const id: ObjectID = ObjectID.generate();
|
|
2213
|
+
idsByName.set(name, id);
|
|
2214
|
+
|
|
2215
|
+
await insert("TeamComplianceSetting", {
|
|
2216
|
+
_id: id.toString(),
|
|
2217
|
+
projectId: projectId.toString(),
|
|
2218
|
+
teamId: teamId.toString(),
|
|
2219
|
+
enabled: true,
|
|
2220
|
+
version: 1,
|
|
2221
|
+
...row,
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
await database.query(
|
|
2226
|
+
backfill.replace(
|
|
2227
|
+
'UPDATE "TeamComplianceSetting"',
|
|
2228
|
+
`UPDATE "${schema}"."TeamComplianceSetting"`,
|
|
2229
|
+
),
|
|
2230
|
+
);
|
|
2231
|
+
|
|
2232
|
+
const after: Record<string, StoredChannelColumns> = {};
|
|
2233
|
+
|
|
2234
|
+
for (const [name] of rows) {
|
|
2235
|
+
after[name] = await storedChannelColumns(idsByName.get(name)!);
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
expect(after).toEqual({
|
|
2239
|
+
"call rule": {
|
|
2240
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2241
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
2242
|
+
},
|
|
2243
|
+
"telegram alert episode rule": {
|
|
2244
|
+
notificationChannels: [ComplianceNotificationChannel.Telegram],
|
|
2245
|
+
notificationChannel: ComplianceNotificationChannel.Telegram,
|
|
2246
|
+
},
|
|
2247
|
+
"any-channel rule": {
|
|
2248
|
+
notificationChannels: null,
|
|
2249
|
+
notificationChannel: null,
|
|
2250
|
+
},
|
|
2251
|
+
"method rule": {
|
|
2252
|
+
notificationChannels: null,
|
|
2253
|
+
notificationChannel: null,
|
|
2254
|
+
},
|
|
2255
|
+
"rule already on a list": {
|
|
2256
|
+
notificationChannels: [
|
|
2257
|
+
ComplianceNotificationChannel.Push,
|
|
2258
|
+
ComplianceNotificationChannel.SMS,
|
|
2259
|
+
],
|
|
2260
|
+
notificationChannel: ComplianceNotificationChannel.Push,
|
|
2261
|
+
},
|
|
2262
|
+
});
|
|
2263
|
+
|
|
2264
|
+
// Each checks what it checked before the migration.
|
|
2265
|
+
for (const [name, channels] of [
|
|
2266
|
+
["call rule", [ComplianceNotificationChannel.Call]],
|
|
2267
|
+
[
|
|
2268
|
+
"telegram alert episode rule",
|
|
2269
|
+
[ComplianceNotificationChannel.Telegram],
|
|
2270
|
+
],
|
|
2271
|
+
["any-channel rule", []],
|
|
2272
|
+
["method rule", []],
|
|
2273
|
+
] as Array<[string, Array<ComplianceNotificationChannel>]>) {
|
|
2274
|
+
expect(
|
|
2275
|
+
(await stored(idsByName.get(name)!))?.notificationChannels,
|
|
2276
|
+
).toEqual(channels);
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
// Running it again changes nothing.
|
|
2280
|
+
await database.query(
|
|
2281
|
+
backfill.replace(
|
|
2282
|
+
'UPDATE "TeamComplianceSetting"',
|
|
2283
|
+
`UPDATE "${schema}"."TeamComplianceSetting"`,
|
|
2284
|
+
),
|
|
2285
|
+
);
|
|
2286
|
+
|
|
2287
|
+
expect(await storedChannelColumns(idsByName.get("call rule")!)).toEqual(
|
|
2288
|
+
{
|
|
2289
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2290
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
2291
|
+
},
|
|
2292
|
+
);
|
|
2293
|
+
});
|
|
2294
|
+
});
|
|
2295
|
+
|
|
2296
|
+
describe("deleting", () => {
|
|
2297
|
+
test("deleting a severity removes its join row and keeps the rule", async () => {
|
|
2298
|
+
const id: ObjectID = await createRule({
|
|
2299
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2300
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2301
|
+
incidentSeverities: asStrings([critical, major]),
|
|
2302
|
+
});
|
|
2303
|
+
|
|
2304
|
+
// What DatabaseService.deleteBy issues once a delete is permitted.
|
|
2305
|
+
await database.query(
|
|
2306
|
+
`DELETE FROM "${schema}"."IncidentSeverity" WHERE "_id" = $1`,
|
|
2307
|
+
[critical.toString()],
|
|
2308
|
+
);
|
|
2309
|
+
|
|
2310
|
+
expect(await stored(id)).toEqual({
|
|
2311
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2312
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2313
|
+
enabled: true,
|
|
2314
|
+
incidentSeverityIds: ids([major]),
|
|
2315
|
+
alertSeverityIds: [],
|
|
2316
|
+
});
|
|
2317
|
+
|
|
2318
|
+
const rule: TeamComplianceSetting | null = await readRule(id);
|
|
2319
|
+
|
|
2320
|
+
expect(toReadSeverities(rule?.incidentSeverities)).toEqual([
|
|
2321
|
+
{
|
|
2322
|
+
id: major.toString(),
|
|
2323
|
+
name: "Major Incident",
|
|
2324
|
+
color: "#FFA500",
|
|
2325
|
+
order: 2,
|
|
2326
|
+
},
|
|
2327
|
+
]);
|
|
2328
|
+
});
|
|
2329
|
+
|
|
2330
|
+
test("deleting an alert severity removes its join row too", async () => {
|
|
2331
|
+
const id: ObjectID = await createRule({
|
|
2332
|
+
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
2333
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
2334
|
+
alertSeverities: asStrings([criticalAlert, warningAlert]),
|
|
2335
|
+
});
|
|
2336
|
+
|
|
2337
|
+
await database.query(
|
|
2338
|
+
`DELETE FROM "${schema}"."AlertSeverity" WHERE "_id" = $1`,
|
|
2339
|
+
[warningAlert.toString()],
|
|
2340
|
+
);
|
|
2341
|
+
|
|
2342
|
+
expect(await joinRows(ALERT_JOIN_TABLE, id)).toEqual(
|
|
2343
|
+
ids([criticalAlert]),
|
|
2344
|
+
);
|
|
2345
|
+
});
|
|
2346
|
+
|
|
2347
|
+
/*
|
|
2348
|
+
* The raw deletes above show the cascade itself. Through the severity
|
|
2349
|
+
* services - the only way the product deletes a severity - a rule the
|
|
2350
|
+
* cascade leaves with no severity is paused rather than left to read
|
|
2351
|
+
* as a rule for every severity.
|
|
2352
|
+
*/
|
|
2353
|
+
test("deleting a rule's only severity through the service pauses the rule; a rule with another severity left keeps it", async () => {
|
|
2354
|
+
const onlyCritical: ObjectID = await createRule({
|
|
2355
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2356
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2357
|
+
incidentSeverities: asStrings([critical]),
|
|
2358
|
+
});
|
|
2359
|
+
const episodeOnlyCritical: ObjectID = await createRule({
|
|
2360
|
+
ruleType: ComplianceRuleType.HasIncidentEpisodeOnCallRules,
|
|
2361
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
2362
|
+
incidentSeverities: asStrings([critical]),
|
|
2363
|
+
});
|
|
2364
|
+
const criticalAndMajor: ObjectID = await createRule({
|
|
2365
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2366
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
2367
|
+
incidentSeverities: asStrings([critical, major]),
|
|
2368
|
+
});
|
|
2369
|
+
const everySeverity: ObjectID = await createRule({
|
|
2370
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2371
|
+
notificationChannels: [ComplianceNotificationChannel.Email],
|
|
2372
|
+
});
|
|
2373
|
+
const alertRule: ObjectID = await createRule({
|
|
2374
|
+
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
2375
|
+
alertSeverities: asStrings([criticalAlert]),
|
|
2376
|
+
});
|
|
2377
|
+
|
|
2378
|
+
await IncidentSeverityService.deleteOneById({
|
|
2379
|
+
id: critical,
|
|
2380
|
+
props: ROOT,
|
|
2381
|
+
});
|
|
2382
|
+
|
|
2383
|
+
expect(await stored(onlyCritical)).toEqual({
|
|
2384
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2385
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2386
|
+
enabled: false,
|
|
2387
|
+
incidentSeverityIds: [],
|
|
2388
|
+
alertSeverityIds: [],
|
|
2389
|
+
});
|
|
2390
|
+
expect(await storedOptions(onlyCritical)).toEqual(MARKED);
|
|
2391
|
+
expect((await stored(episodeOnlyCritical))?.enabled).toBe(false);
|
|
2392
|
+
expect(await storedOptions(episodeOnlyCritical)).toEqual(MARKED);
|
|
2393
|
+
expect(await storedOptions(criticalAndMajor)).toBeNull();
|
|
2394
|
+
expect(await storedOptions(everySeverity)).toBeNull();
|
|
2395
|
+
|
|
2396
|
+
expect(await stored(criticalAndMajor)).toEqual({
|
|
2397
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2398
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
2399
|
+
enabled: true,
|
|
2400
|
+
incidentSeverityIds: ids([major]),
|
|
2401
|
+
alertSeverityIds: [],
|
|
2402
|
+
});
|
|
2403
|
+
expect((await stored(everySeverity))?.enabled).toBe(true);
|
|
2404
|
+
expect(await stored(alertRule)).toMatchObject({
|
|
2405
|
+
enabled: true,
|
|
2406
|
+
alertSeverityIds: ids([criticalAlert]),
|
|
2407
|
+
});
|
|
2408
|
+
});
|
|
2409
|
+
|
|
2410
|
+
test("deleting an alert rule's only severity through the service pauses it too", async () => {
|
|
2411
|
+
const onlyWarning: ObjectID = await createRule({
|
|
2412
|
+
ruleType: ComplianceRuleType.HasAlertEpisodeOnCallRules,
|
|
2413
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
2414
|
+
alertSeverities: asStrings([warningAlert]),
|
|
2415
|
+
});
|
|
2416
|
+
const incidentRule: ObjectID = await createRule({
|
|
2417
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2418
|
+
incidentSeverities: asStrings([critical]),
|
|
2419
|
+
});
|
|
2420
|
+
|
|
2421
|
+
await AlertSeverityService.deleteOneById({
|
|
2422
|
+
id: warningAlert,
|
|
2423
|
+
props: ROOT,
|
|
2424
|
+
});
|
|
2425
|
+
|
|
2426
|
+
expect(await stored(onlyWarning)).toMatchObject({
|
|
2427
|
+
enabled: false,
|
|
2428
|
+
alertSeverityIds: [],
|
|
2429
|
+
});
|
|
2430
|
+
expect((await stored(incidentRule))?.enabled).toBe(true);
|
|
1621
2431
|
});
|
|
1622
2432
|
|
|
1623
2433
|
test.each([
|
|
@@ -1629,19 +2439,19 @@ describePostgres(
|
|
|
1629
2439
|
const both: ObjectID = isAlert
|
|
1630
2440
|
? await createRule({
|
|
1631
2441
|
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
1632
|
-
|
|
2442
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1633
2443
|
alertSeverities: asStrings([criticalAlert, warningAlert]),
|
|
1634
2444
|
})
|
|
1635
2445
|
: await createRule({
|
|
1636
2446
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1637
|
-
|
|
2447
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1638
2448
|
incidentSeverities: asStrings([critical, major]),
|
|
1639
2449
|
});
|
|
1640
2450
|
|
|
1641
2451
|
// A rule with a severity neither delete touches.
|
|
1642
2452
|
const keepsMinor: ObjectID = await createRule({
|
|
1643
2453
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1644
|
-
|
|
2454
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1645
2455
|
incidentSeverities: asStrings([critical, minor]),
|
|
1646
2456
|
});
|
|
1647
2457
|
|
|
@@ -1683,7 +2493,7 @@ describePostgres(
|
|
|
1683
2493
|
test("a rule an admin had paused is marked too, so switching it on later cannot widen it", async () => {
|
|
1684
2494
|
const paused: ObjectID = await createRule({
|
|
1685
2495
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1686
|
-
|
|
2496
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1687
2497
|
incidentSeverities: asStrings([critical]),
|
|
1688
2498
|
enabled: false,
|
|
1689
2499
|
});
|
|
@@ -1710,11 +2520,11 @@ describePostgres(
|
|
|
1710
2520
|
test("a rule a delete emptied duplicates nothing, cannot be switched on as it is, and is re-scoped from its edit form", async () => {
|
|
1711
2521
|
const everySeverity: ObjectID = await createRule({
|
|
1712
2522
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1713
|
-
|
|
2523
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1714
2524
|
});
|
|
1715
2525
|
const onlyCritical: ObjectID = await createRule({
|
|
1716
2526
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1717
|
-
|
|
2527
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1718
2528
|
incidentSeverities: asStrings([critical]),
|
|
1719
2529
|
});
|
|
1720
2530
|
|
|
@@ -1726,7 +2536,7 @@ describePostgres(
|
|
|
1726
2536
|
// The every-severity rule's edit form sends its whole scope.
|
|
1727
2537
|
await updateRule(everySeverity, {
|
|
1728
2538
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1729
|
-
|
|
2539
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1730
2540
|
incidentSeverities: [],
|
|
1731
2541
|
alertSeverities: [],
|
|
1732
2542
|
enabled: false,
|
|
@@ -1744,7 +2554,7 @@ describePostgres(
|
|
|
1744
2554
|
// The emptied rule's edit form: new severities, switched back on.
|
|
1745
2555
|
await updateRule(onlyCritical, {
|
|
1746
2556
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1747
|
-
|
|
2557
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1748
2558
|
incidentSeverities: asJson([major]),
|
|
1749
2559
|
alertSeverities: [],
|
|
1750
2560
|
enabled: true,
|
|
@@ -1752,7 +2562,7 @@ describePostgres(
|
|
|
1752
2562
|
|
|
1753
2563
|
expect(await stored(onlyCritical)).toEqual({
|
|
1754
2564
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1755
|
-
|
|
2565
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1756
2566
|
enabled: true,
|
|
1757
2567
|
incidentSeverityIds: ids([major]),
|
|
1758
2568
|
alertSeverityIds: [],
|
|
@@ -1768,7 +2578,7 @@ describePostgres(
|
|
|
1768
2578
|
test("re-scoping an emptied rule keeps every other option it carries", async () => {
|
|
1769
2579
|
const onlyCritical: ObjectID = await createRule({
|
|
1770
2580
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1771
|
-
|
|
2581
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1772
2582
|
incidentSeverities: asStrings([critical]),
|
|
1773
2583
|
});
|
|
1774
2584
|
|
|
@@ -1797,7 +2607,7 @@ describePostgres(
|
|
|
1797
2607
|
test("a delete the database refuses - the severity is still in use - pauses nothing", async () => {
|
|
1798
2608
|
const onlyCritical: ObjectID = await createRule({
|
|
1799
2609
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1800
|
-
|
|
2610
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1801
2611
|
incidentSeverities: asStrings([critical]),
|
|
1802
2612
|
});
|
|
1803
2613
|
|
|
@@ -1829,7 +2639,7 @@ describePostgres(
|
|
|
1829
2639
|
|
|
1830
2640
|
expect(await stored(onlyCritical)).toEqual({
|
|
1831
2641
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1832
|
-
|
|
2642
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1833
2643
|
enabled: true,
|
|
1834
2644
|
incidentSeverityIds: ids([critical]),
|
|
1835
2645
|
alertSeverityIds: [],
|
|
@@ -1839,13 +2649,13 @@ describePostgres(
|
|
|
1839
2649
|
test("deleting a rule through the service removes its join rows and nobody else's", async () => {
|
|
1840
2650
|
const id: ObjectID = await createRule({
|
|
1841
2651
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1842
|
-
|
|
2652
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1843
2653
|
incidentSeverities: asStrings([critical, major]),
|
|
1844
2654
|
});
|
|
1845
2655
|
|
|
1846
2656
|
const sibling: ObjectID = await createRule({
|
|
1847
2657
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1848
|
-
|
|
2658
|
+
notificationChannels: [ComplianceNotificationChannel.Push],
|
|
1849
2659
|
incidentSeverities: asStrings([critical]),
|
|
1850
2660
|
});
|
|
1851
2661
|
|
|
@@ -1887,7 +2697,7 @@ describePostgres(
|
|
|
1887
2697
|
const id: ObjectID = await createRule(
|
|
1888
2698
|
{
|
|
1889
2699
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1890
|
-
|
|
2700
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1891
2701
|
incidentSeverities: asIncidentModels([critical]),
|
|
1892
2702
|
},
|
|
1893
2703
|
admin,
|
|
@@ -1895,7 +2705,7 @@ describePostgres(
|
|
|
1895
2705
|
|
|
1896
2706
|
expect(await stored(id)).toEqual({
|
|
1897
2707
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1898
|
-
|
|
2708
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1899
2709
|
enabled: true,
|
|
1900
2710
|
incidentSeverityIds: ids([critical]),
|
|
1901
2711
|
alertSeverityIds: [],
|
|
@@ -1926,7 +2736,7 @@ describePostgres(
|
|
|
1926
2736
|
createRule(
|
|
1927
2737
|
{
|
|
1928
2738
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1929
|
-
|
|
2739
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1930
2740
|
incidentSeverities: asJson([major, critical]),
|
|
1931
2741
|
},
|
|
1932
2742
|
admin,
|
|
@@ -1941,7 +2751,7 @@ describePostgres(
|
|
|
1941
2751
|
|
|
1942
2752
|
const onlyCritical: ObjectID = await createRule({
|
|
1943
2753
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1944
|
-
|
|
2754
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1945
2755
|
incidentSeverities: asStrings([critical]),
|
|
1946
2756
|
});
|
|
1947
2757
|
|
|
@@ -1973,7 +2783,7 @@ describePostgres(
|
|
|
1973
2783
|
test("a caller who may not change the project's rules learns nothing about its severities or rules", async () => {
|
|
1974
2784
|
await createRule({
|
|
1975
2785
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
1976
|
-
|
|
2786
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
1977
2787
|
incidentSeverities: asStrings([critical]),
|
|
1978
2788
|
});
|
|
1979
2789
|
|
|
@@ -1997,7 +2807,7 @@ describePostgres(
|
|
|
1997
2807
|
createRule(
|
|
1998
2808
|
{
|
|
1999
2809
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2000
|
-
|
|
2810
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2001
2811
|
incidentSeverities: asStrings([severity]),
|
|
2002
2812
|
},
|
|
2003
2813
|
props,
|
|
@@ -2009,6 +2819,88 @@ describePostgres(
|
|
|
2009
2819
|
expect(await countRules()).toBe(1);
|
|
2010
2820
|
});
|
|
2011
2821
|
|
|
2822
|
+
/*
|
|
2823
|
+
* The hooks write notificationChannel beside whatever list is sent,
|
|
2824
|
+
* after the caller's column permissions were checked against the
|
|
2825
|
+
* payload - so the column they add must pass the same check the
|
|
2826
|
+
* update makes again once they return.
|
|
2827
|
+
*/
|
|
2828
|
+
test("a team editor sets a rule's channels with the list alone, or with the older column alone", async () => {
|
|
2829
|
+
const editor: DatabaseCommonInteractionProps = memberProps(projectId, [
|
|
2830
|
+
Permission.ReadProjectTeam,
|
|
2831
|
+
Permission.EditProjectTeam,
|
|
2832
|
+
]);
|
|
2833
|
+
|
|
2834
|
+
const id: ObjectID = await createRule(
|
|
2835
|
+
{
|
|
2836
|
+
ruleType: ComplianceRuleType.HasAlertOnCallRules,
|
|
2837
|
+
notificationChannels: [
|
|
2838
|
+
ComplianceNotificationChannel.Push,
|
|
2839
|
+
ComplianceNotificationChannel.SMS,
|
|
2840
|
+
],
|
|
2841
|
+
alertSeverities: asStrings([criticalAlert]),
|
|
2842
|
+
},
|
|
2843
|
+
editor,
|
|
2844
|
+
);
|
|
2845
|
+
|
|
2846
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
2847
|
+
notificationChannels: [
|
|
2848
|
+
ComplianceNotificationChannel.SMS,
|
|
2849
|
+
ComplianceNotificationChannel.Push,
|
|
2850
|
+
],
|
|
2851
|
+
notificationChannel: ComplianceNotificationChannel.SMS,
|
|
2852
|
+
});
|
|
2853
|
+
|
|
2854
|
+
await updateRule(
|
|
2855
|
+
id,
|
|
2856
|
+
{ notificationChannels: [ComplianceNotificationChannel.Call] },
|
|
2857
|
+
editor,
|
|
2858
|
+
);
|
|
2859
|
+
|
|
2860
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
2861
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2862
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
2863
|
+
});
|
|
2864
|
+
|
|
2865
|
+
await updateRule(
|
|
2866
|
+
id,
|
|
2867
|
+
{ notificationChannel: ComplianceNotificationChannel.Email },
|
|
2868
|
+
editor,
|
|
2869
|
+
);
|
|
2870
|
+
|
|
2871
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
2872
|
+
notificationChannels: [ComplianceNotificationChannel.Email],
|
|
2873
|
+
notificationChannel: ComplianceNotificationChannel.Email,
|
|
2874
|
+
});
|
|
2875
|
+
});
|
|
2876
|
+
|
|
2877
|
+
test("a member who may only read the project's teams changes neither channel column", async () => {
|
|
2878
|
+
const reader: DatabaseCommonInteractionProps = memberProps(projectId, [
|
|
2879
|
+
Permission.ProjectMember,
|
|
2880
|
+
Permission.ReadProjectTeam,
|
|
2881
|
+
]);
|
|
2882
|
+
|
|
2883
|
+
const id: ObjectID = await createRule({
|
|
2884
|
+
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2885
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2886
|
+
incidentSeverities: asStrings([critical]),
|
|
2887
|
+
});
|
|
2888
|
+
|
|
2889
|
+
for (const data of [
|
|
2890
|
+
{ notificationChannels: [ComplianceNotificationChannel.Webhook] },
|
|
2891
|
+
{ notificationChannel: ComplianceNotificationChannel.Webhook },
|
|
2892
|
+
]) {
|
|
2893
|
+
await expect(updateRule(id, data, reader)).rejects.toThrow(
|
|
2894
|
+
NotAuthorizedException,
|
|
2895
|
+
);
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
expect(await storedChannelColumns(id)).toEqual({
|
|
2899
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2900
|
+
notificationChannel: ComplianceNotificationChannel.Call,
|
|
2901
|
+
});
|
|
2902
|
+
});
|
|
2903
|
+
|
|
2012
2904
|
test("a team editor creates and rescopes a rule; cleared options pass the permission check", async () => {
|
|
2013
2905
|
const editor: DatabaseCommonInteractionProps = memberProps(projectId, [
|
|
2014
2906
|
Permission.ReadProjectTeam,
|
|
@@ -2019,7 +2911,7 @@ describePostgres(
|
|
|
2019
2911
|
const method: ObjectID = await createRule(
|
|
2020
2912
|
{
|
|
2021
2913
|
ruleType: ComplianceRuleType.HasNotificationCallMethod,
|
|
2022
|
-
|
|
2914
|
+
notificationChannels: [ComplianceNotificationChannel.SMS],
|
|
2023
2915
|
incidentSeverities: asStrings([critical]),
|
|
2024
2916
|
},
|
|
2025
2917
|
editor,
|
|
@@ -2027,7 +2919,7 @@ describePostgres(
|
|
|
2027
2919
|
|
|
2028
2920
|
expect(await stored(method)).toEqual({
|
|
2029
2921
|
ruleType: ComplianceRuleType.HasNotificationCallMethod,
|
|
2030
|
-
|
|
2922
|
+
notificationChannels: [],
|
|
2031
2923
|
enabled: true,
|
|
2032
2924
|
incidentSeverityIds: [],
|
|
2033
2925
|
alertSeverityIds: [],
|
|
@@ -2036,7 +2928,7 @@ describePostgres(
|
|
|
2036
2928
|
const id: ObjectID = await createRule(
|
|
2037
2929
|
{
|
|
2038
2930
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2039
|
-
|
|
2931
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2040
2932
|
incidentSeverities: asIncidentModels([critical]),
|
|
2041
2933
|
alertSeverities: asStrings([criticalAlert]),
|
|
2042
2934
|
},
|
|
@@ -2061,7 +2953,7 @@ describePostgres(
|
|
|
2061
2953
|
|
|
2062
2954
|
expect(await stored(id)).toEqual({
|
|
2063
2955
|
ruleType: ComplianceRuleType.HasNotificationPushMethod,
|
|
2064
|
-
|
|
2956
|
+
notificationChannels: [],
|
|
2065
2957
|
enabled: true,
|
|
2066
2958
|
incidentSeverityIds: [],
|
|
2067
2959
|
alertSeverityIds: [],
|
|
@@ -2129,7 +3021,7 @@ describePostgres(
|
|
|
2129
3021
|
|
|
2130
3022
|
const onlyCritical: ObjectID = await createRule({
|
|
2131
3023
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2132
|
-
|
|
3024
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2133
3025
|
incidentSeverities: asStrings([critical]),
|
|
2134
3026
|
});
|
|
2135
3027
|
|
|
@@ -2170,7 +3062,7 @@ describePostgres(
|
|
|
2170
3062
|
test("cannot rescope another project's rule", async () => {
|
|
2171
3063
|
const id: ObjectID = await createRule({
|
|
2172
3064
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2173
|
-
|
|
3065
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2174
3066
|
incidentSeverities: asStrings([critical]),
|
|
2175
3067
|
});
|
|
2176
3068
|
|
|
@@ -2204,7 +3096,7 @@ describePostgres(
|
|
|
2204
3096
|
createRule(
|
|
2205
3097
|
{
|
|
2206
3098
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2207
|
-
|
|
3099
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2208
3100
|
incidentSeverities: asIncidentModels([otherProjectCritical]),
|
|
2209
3101
|
projectId: otherProjectId,
|
|
2210
3102
|
},
|
|
@@ -2218,7 +3110,7 @@ describePostgres(
|
|
|
2218
3110
|
const id: ObjectID = await createRule(
|
|
2219
3111
|
{
|
|
2220
3112
|
ruleType: ComplianceRuleType.HasIncidentOnCallRules,
|
|
2221
|
-
|
|
3113
|
+
notificationChannels: [ComplianceNotificationChannel.Call],
|
|
2222
3114
|
incidentSeverities: asIncidentModels([critical]),
|
|
2223
3115
|
projectId: otherProjectId,
|
|
2224
3116
|
},
|