@oneuptime/common 12.0.18 → 12.0.20
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/EnterpriseLicense.ts +23 -0
- package/Models/DatabaseModels/Index.ts +4 -2
- package/Models/DatabaseModels/Monitor.ts +39 -9
- package/Models/DatabaseModels/UserMicrosoftTeams.ts +344 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +144 -8
- package/Models/DatabaseModels/UserNotificationSetting.ts +34 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +95 -0
- package/Models/DatabaseModels/UserSlack.ts +341 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +9 -0
- package/Server/API/EnterpriseLicenseAPI.ts +94 -19
- package/Server/API/UserMicrosoftTeamsAPI.ts +127 -0
- package/Server/API/UserSlackAPI.ts +125 -0
- package/Server/EnvironmentConfig.ts +29 -107
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.ts +117 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.ts +197 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/Queue.ts +7 -0
- package/Server/Services/EnterpriseLicenseService.ts +60 -0
- package/Server/Services/Index.ts +6 -2
- package/Server/Services/LlmLogService.ts +25 -9
- package/Server/Services/OnCallReadinessService.ts +86 -2
- package/Server/Services/ProjectService.ts +171 -0
- package/Server/Services/UserMicrosoftTeamsService.ts +208 -0
- package/Server/Services/UserNotificationMethodAdminService.ts +167 -5
- package/Server/Services/UserNotificationRuleAdminService.ts +40 -6
- package/Server/Services/UserNotificationRuleService.ts +589 -11
- package/Server/Services/UserNotificationSettingService.ts +138 -0
- package/Server/Services/UserService.ts +28 -0
- package/Server/Services/UserSlackService.ts +218 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +67 -1
- package/Server/Services/WorkspaceUserAuthTokenService.ts +73 -0
- package/Server/Services/WorkspaceUserNotificationService.ts +190 -0
- package/Server/Utils/Marketing/MarketingEventUtil.ts +145 -0
- package/Server/Utils/Marketing/MarketingEventWebhook.ts +114 -0
- package/Server/Utils/Monitor/MonitorLogUtil.ts +14 -1
- package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +321 -0
- package/Server/Utils/Response.ts +2 -2
- package/Server/Utils/StartServer.ts +2 -2
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +191 -4
- package/Server/Views/Partials/AnalyticsConsent.ejs +533 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +22 -14
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +22 -11
- package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +465 -0
- package/Tests/App/Dashboard/DashboardChartWidgetZoom.test.tsx +302 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +408 -0
- package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +474 -0
- package/Tests/App/Dashboard/MetricSeriesInvestigateMenu.test.tsx +368 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +37 -1
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +18 -10
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +27 -1
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +214 -0
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +763 -0
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +145 -26
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +2 -2
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +11 -1
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +22 -8
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +18 -2
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +5 -1
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +640 -0
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +246 -22
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +136 -8
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +191 -8
- package/Tests/Server/Services/OnCallReadinessService.test.ts +343 -18
- package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +138 -0
- package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +516 -0
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +5 -1
- package/Tests/Server/Services/UserMicrosoftTeamsService.test.ts +343 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +209 -8
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +22 -6
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +12 -6
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +37 -3
- package/Tests/Server/Services/UserNotificationRuleWorkspaceDelivery.test.ts +669 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +410 -0
- package/Tests/Server/Services/UserSlackService.test.ts +407 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenDisconnectCascade.test.ts +224 -0
- package/Tests/Server/Services/WorkspaceUserAuthTokenNotificationMethodCascade.test.ts +189 -0
- package/Tests/Server/Services/WorkspaceUserNotificationService.test.ts +496 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +30 -17
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +8 -3
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +72 -3
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +22 -18
- package/Tests/Server/Types/Database/Permissions/WorkspaceMethodStampedColumnCreate.test.ts +178 -0
- package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +259 -0
- package/Tests/Server/Utils/Marketing/MarketingEventWebhook.test.ts +257 -0
- package/Tests/Server/Utils/Monitor/MonitorLogUtilRedaction.test.ts +300 -0
- package/Tests/Server/Utils/Monitor/MonitorPayloadRedaction.test.ts +381 -0
- package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +53 -0
- package/Tests/Server/Utils/Runbook/RunbookExecutePermission.test.ts +228 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayErasureTombstone.test.ts +189 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +205 -0
- package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +275 -0
- package/Tests/Server/Utils/Telemetry/TelemetryContext.test.ts +279 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +454 -0
- package/Tests/Server/Views/AnalyticsConsentPartial.test.ts +241 -0
- package/Tests/UI/Components/Charts/ChartTooltipSorted.test.tsx +129 -0
- package/Tests/UI/Components/Charts/TooltipEntries.test.ts +155 -0
- package/Tests/UI/Components/Detail/DetailFieldErrors.test.tsx +347 -0
- package/Tests/UI/Components/Forms/BasicFormStepValidation.test.tsx +392 -0
- package/Tests/UI/Components/Forms/ValidationFormSteps.test.ts +549 -0
- package/Tests/UI/Utils/NotificationMethodUtil.test.ts +137 -9
- package/Tests/UI/Utils/PermissionGate.test.ts +105 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +562 -0
- package/Types/Analytics/RevenueEvent.ts +1 -0
- package/Types/Marketing/MarketingEvent.ts +140 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +8 -1
- package/UI/Components/Charts/Bar/BarChart.tsx +8 -1
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +19 -4
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +20 -2
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +19 -4
- package/UI/Components/Charts/ChartLibrary/Utils/TooltipEntries.ts +105 -0
- package/UI/Components/Charts/Line/LineChart.tsx +8 -1
- package/UI/Components/Detail/Detail.tsx +18 -1
- package/UI/Utils/NotificationMethodUtil.ts +41 -1
- package/UI/Utils/PermissionGate.ts +56 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +244 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +24 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -2
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +39 -9
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js +363 -0
- package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +145 -8
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationSetting.js +38 -0
- package/build/dist/Models/DatabaseModels/UserNotificationSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +96 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSlack.js +361 -0
- package/build/dist/Models/DatabaseModels/UserSlack.js.map +1 -0
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +66 -12
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +82 -0
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -0
- package/build/dist/Server/API/UserSlackAPI.js +81 -0
- package/build/dist/Server/API/UserSlackAPI.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +25 -70
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js +37 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js +106 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js +78 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +7 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +65 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +6 -2
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LlmLogService.js +25 -9
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallReadinessService.js +74 -2
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +144 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/UserMicrosoftTeamsService.js +183 -0
- package/build/dist/Server/Services/UserMicrosoftTeamsService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +138 -2
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +32 -4
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +499 -67
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +118 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +26 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSlackService.js +195 -0
- package/build/dist/Server/Services/UserSlackService.js.map +1 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +64 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +70 -0
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserNotificationService.js +129 -0
- package/build/dist/Server/Services/WorkspaceUserNotificationService.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +94 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js +93 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +12 -1
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +233 -0
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Response.js +2 -2
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +2 -2
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +141 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Analytics/RevenueEvent.js +1 -0
- package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingEvent.js +82 -0
- package/build/dist/Types/Marketing/MarketingEvent.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +9 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +9 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +22 -13
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +27 -15
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +27 -18
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/TooltipEntries.js +71 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/TooltipEntries.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +9 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +17 -1
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Utils/NotificationMethodUtil.js +33 -1
- package/build/dist/UI/Utils/NotificationMethodUtil.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +32 -0
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +174 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +1 -0
- package/package.json +1 -1
- package/Models/DatabaseModels/MarketingConversion.ts +0 -410
- package/Server/Services/MarketingConversionService.ts +0 -10
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +0 -215
- package/Server/Utils/Marketing/ConversionUploadProviders.ts +0 -22
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +0 -333
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +0 -185
- package/Server/Utils/Marketing/Providers/Meta.ts +0 -182
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +0 -223
- package/Server/Utils/Marketing/Providers/Reddit.ts +0 -208
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +0 -315
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +0 -300
- package/Tests/Server/Utils/Marketing/GoogleAds.test.ts +0 -592
- package/Tests/Server/Utils/Marketing/LinkedIn.test.ts +0 -282
- package/Tests/Server/Utils/Marketing/Meta.test.ts +0 -304
- package/Tests/Server/Utils/Marketing/MicrosoftAds.test.ts +0 -263
- package/Tests/Server/Utils/Marketing/Reddit.test.ts +0 -259
- package/Types/Marketing/MarketingConversion.ts +0 -53
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +0 -445
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +0 -1
- package/build/dist/Server/Services/MarketingConversionService.js +0 -9
- package/build/dist/Server/Services/MarketingConversionService.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +0 -93
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +0 -20
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +0 -221
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +0 -137
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +0 -133
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +0 -143
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +0 -145
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +0 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +0 -52
- package/build/dist/Types/Marketing/MarketingConversion.js.map +0 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Slack and Microsoft Teams as user notification methods.
|
|
5
|
+
*
|
|
6
|
+
* Two new per-user method tables (UserSlack / UserMicrosoftTeams — pointers at
|
|
7
|
+
* the user's OAuth workspace link, created verified), the notification-rule
|
|
8
|
+
* and on-call timeline foreign keys that let rules route pages to them, and
|
|
9
|
+
* the two per-event toggles on UserNotificationSetting.
|
|
10
|
+
*/
|
|
11
|
+
export class AddUserSlackAndMicrosoftTeams1789000000000
|
|
12
|
+
implements MigrationInterface
|
|
13
|
+
{
|
|
14
|
+
public name = "AddUserSlackAndMicrosoftTeams1789000000000";
|
|
15
|
+
|
|
16
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
17
|
+
await queryRunner.query(
|
|
18
|
+
`CREATE TABLE "UserSlack" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "slackUserId" character varying(100), "slackUserName" character varying(100), "userId" uuid, "createdByUserId" uuid, "deletedByUserId" uuid, "isVerified" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_86de4cd76b41a08811fc403e23a" PRIMARY KEY ("_id"))`,
|
|
19
|
+
);
|
|
20
|
+
await queryRunner.query(
|
|
21
|
+
`CREATE INDEX "IDX_d5dd2503bf422c6a19946216e1" ON "UserSlack" ("projectId") `,
|
|
22
|
+
);
|
|
23
|
+
await queryRunner.query(
|
|
24
|
+
`CREATE INDEX "IDX_abe4265455b18cd43a94bb84ed" ON "UserSlack" ("slackUserId") `,
|
|
25
|
+
);
|
|
26
|
+
await queryRunner.query(
|
|
27
|
+
`CREATE INDEX "IDX_9c8fa391e949f53f670dabe222" ON "UserSlack" ("userId") `,
|
|
28
|
+
);
|
|
29
|
+
await queryRunner.query(
|
|
30
|
+
`CREATE TABLE "UserMicrosoftTeams" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "microsoftTeamsUserId" character varying(100), "microsoftTeamsUserName" character varying(100), "userId" uuid, "createdByUserId" uuid, "deletedByUserId" uuid, "isVerified" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_9e2c27aadbc24a991c68e55c130" PRIMARY KEY ("_id"))`,
|
|
31
|
+
);
|
|
32
|
+
await queryRunner.query(
|
|
33
|
+
`CREATE INDEX "IDX_cebf1edfa5f30a7e597633bddf" ON "UserMicrosoftTeams" ("projectId") `,
|
|
34
|
+
);
|
|
35
|
+
await queryRunner.query(
|
|
36
|
+
`CREATE INDEX "IDX_a746ef4fd29b03ac5abe8f4e4c" ON "UserMicrosoftTeams" ("microsoftTeamsUserId") `,
|
|
37
|
+
);
|
|
38
|
+
await queryRunner.query(
|
|
39
|
+
`CREATE INDEX "IDX_e4405f9dacd3d1e3c363e8dbd3" ON "UserMicrosoftTeams" ("userId") `,
|
|
40
|
+
);
|
|
41
|
+
await queryRunner.query(
|
|
42
|
+
`ALTER TABLE "UserNotificationRule" ADD "userSlackId" uuid`,
|
|
43
|
+
);
|
|
44
|
+
await queryRunner.query(
|
|
45
|
+
`ALTER TABLE "UserNotificationRule" ADD "userMicrosoftTeamsId" uuid`,
|
|
46
|
+
);
|
|
47
|
+
await queryRunner.query(
|
|
48
|
+
`ALTER TABLE "UserOnCallLogTimeline" ADD "userSlackId" uuid`,
|
|
49
|
+
);
|
|
50
|
+
await queryRunner.query(
|
|
51
|
+
`ALTER TABLE "UserOnCallLogTimeline" ADD "userMicrosoftTeamsId" uuid`,
|
|
52
|
+
);
|
|
53
|
+
await queryRunner.query(
|
|
54
|
+
`ALTER TABLE "UserNotificationSetting" ADD "alertBySlack" boolean NOT NULL DEFAULT false`,
|
|
55
|
+
);
|
|
56
|
+
await queryRunner.query(
|
|
57
|
+
`ALTER TABLE "UserNotificationSetting" ADD "alertByMicrosoftTeams" boolean NOT NULL DEFAULT false`,
|
|
58
|
+
);
|
|
59
|
+
await queryRunner.query(
|
|
60
|
+
`CREATE INDEX "IDX_0c24badba9b152d08700f7d8aa" ON "UserNotificationRule" ("userSlackId") `,
|
|
61
|
+
);
|
|
62
|
+
await queryRunner.query(
|
|
63
|
+
`CREATE INDEX "IDX_3dc4e1c367eab9fd36b7983e44" ON "UserNotificationRule" ("userMicrosoftTeamsId") `,
|
|
64
|
+
);
|
|
65
|
+
await queryRunner.query(
|
|
66
|
+
`CREATE INDEX "IDX_d51ef7b2a8b813d37e94890ff7" ON "UserOnCallLogTimeline" ("userSlackId") `,
|
|
67
|
+
);
|
|
68
|
+
await queryRunner.query(
|
|
69
|
+
`CREATE INDEX "IDX_a7206c19df5cdfe02cf3215a64" ON "UserOnCallLogTimeline" ("userMicrosoftTeamsId") `,
|
|
70
|
+
);
|
|
71
|
+
await queryRunner.query(
|
|
72
|
+
`ALTER TABLE "UserSlack" ADD CONSTRAINT "FK_d5dd2503bf422c6a19946216e19" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
73
|
+
);
|
|
74
|
+
await queryRunner.query(
|
|
75
|
+
`ALTER TABLE "UserSlack" ADD CONSTRAINT "FK_9c8fa391e949f53f670dabe2220" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
76
|
+
);
|
|
77
|
+
await queryRunner.query(
|
|
78
|
+
`ALTER TABLE "UserSlack" ADD CONSTRAINT "FK_fd38a9ee050702437ed323f21fb" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
79
|
+
);
|
|
80
|
+
await queryRunner.query(
|
|
81
|
+
`ALTER TABLE "UserSlack" ADD CONSTRAINT "FK_2f058862227400121f90925d65e" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
82
|
+
);
|
|
83
|
+
await queryRunner.query(
|
|
84
|
+
`ALTER TABLE "UserMicrosoftTeams" ADD CONSTRAINT "FK_cebf1edfa5f30a7e597633bddf9" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
85
|
+
);
|
|
86
|
+
await queryRunner.query(
|
|
87
|
+
`ALTER TABLE "UserMicrosoftTeams" ADD CONSTRAINT "FK_e4405f9dacd3d1e3c363e8dbd30" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
88
|
+
);
|
|
89
|
+
await queryRunner.query(
|
|
90
|
+
`ALTER TABLE "UserMicrosoftTeams" ADD CONSTRAINT "FK_81443b1ab79d63b7700f3d16c84" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
91
|
+
);
|
|
92
|
+
await queryRunner.query(
|
|
93
|
+
`ALTER TABLE "UserMicrosoftTeams" ADD CONSTRAINT "FK_1d7cfdf5a4e314cf4b4cc7873e0" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
94
|
+
);
|
|
95
|
+
await queryRunner.query(
|
|
96
|
+
`ALTER TABLE "UserNotificationRule" ADD CONSTRAINT "FK_0c24badba9b152d08700f7d8aa8" FOREIGN KEY ("userSlackId") REFERENCES "UserSlack"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
97
|
+
);
|
|
98
|
+
await queryRunner.query(
|
|
99
|
+
`ALTER TABLE "UserNotificationRule" ADD CONSTRAINT "FK_3dc4e1c367eab9fd36b7983e444" FOREIGN KEY ("userMicrosoftTeamsId") REFERENCES "UserMicrosoftTeams"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
100
|
+
);
|
|
101
|
+
await queryRunner.query(
|
|
102
|
+
`ALTER TABLE "UserOnCallLogTimeline" ADD CONSTRAINT "FK_d51ef7b2a8b813d37e94890ff77" FOREIGN KEY ("userSlackId") REFERENCES "UserSlack"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
103
|
+
);
|
|
104
|
+
await queryRunner.query(
|
|
105
|
+
`ALTER TABLE "UserOnCallLogTimeline" ADD CONSTRAINT "FK_a7206c19df5cdfe02cf3215a64c" FOREIGN KEY ("userMicrosoftTeamsId") REFERENCES "UserMicrosoftTeams"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
110
|
+
await queryRunner.query(
|
|
111
|
+
`ALTER TABLE "UserOnCallLogTimeline" DROP CONSTRAINT "FK_a7206c19df5cdfe02cf3215a64c"`,
|
|
112
|
+
);
|
|
113
|
+
await queryRunner.query(
|
|
114
|
+
`ALTER TABLE "UserOnCallLogTimeline" DROP CONSTRAINT "FK_d51ef7b2a8b813d37e94890ff77"`,
|
|
115
|
+
);
|
|
116
|
+
await queryRunner.query(
|
|
117
|
+
`ALTER TABLE "UserNotificationRule" DROP CONSTRAINT "FK_3dc4e1c367eab9fd36b7983e444"`,
|
|
118
|
+
);
|
|
119
|
+
await queryRunner.query(
|
|
120
|
+
`ALTER TABLE "UserNotificationRule" DROP CONSTRAINT "FK_0c24badba9b152d08700f7d8aa8"`,
|
|
121
|
+
);
|
|
122
|
+
await queryRunner.query(
|
|
123
|
+
`ALTER TABLE "UserMicrosoftTeams" DROP CONSTRAINT "FK_1d7cfdf5a4e314cf4b4cc7873e0"`,
|
|
124
|
+
);
|
|
125
|
+
await queryRunner.query(
|
|
126
|
+
`ALTER TABLE "UserMicrosoftTeams" DROP CONSTRAINT "FK_81443b1ab79d63b7700f3d16c84"`,
|
|
127
|
+
);
|
|
128
|
+
await queryRunner.query(
|
|
129
|
+
`ALTER TABLE "UserMicrosoftTeams" DROP CONSTRAINT "FK_e4405f9dacd3d1e3c363e8dbd30"`,
|
|
130
|
+
);
|
|
131
|
+
await queryRunner.query(
|
|
132
|
+
`ALTER TABLE "UserMicrosoftTeams" DROP CONSTRAINT "FK_cebf1edfa5f30a7e597633bddf9"`,
|
|
133
|
+
);
|
|
134
|
+
await queryRunner.query(
|
|
135
|
+
`ALTER TABLE "UserSlack" DROP CONSTRAINT "FK_2f058862227400121f90925d65e"`,
|
|
136
|
+
);
|
|
137
|
+
await queryRunner.query(
|
|
138
|
+
`ALTER TABLE "UserSlack" DROP CONSTRAINT "FK_fd38a9ee050702437ed323f21fb"`,
|
|
139
|
+
);
|
|
140
|
+
await queryRunner.query(
|
|
141
|
+
`ALTER TABLE "UserSlack" DROP CONSTRAINT "FK_9c8fa391e949f53f670dabe2220"`,
|
|
142
|
+
);
|
|
143
|
+
await queryRunner.query(
|
|
144
|
+
`ALTER TABLE "UserSlack" DROP CONSTRAINT "FK_d5dd2503bf422c6a19946216e19"`,
|
|
145
|
+
);
|
|
146
|
+
await queryRunner.query(
|
|
147
|
+
`DROP INDEX "public"."IDX_a7206c19df5cdfe02cf3215a64"`,
|
|
148
|
+
);
|
|
149
|
+
await queryRunner.query(
|
|
150
|
+
`DROP INDEX "public"."IDX_d51ef7b2a8b813d37e94890ff7"`,
|
|
151
|
+
);
|
|
152
|
+
await queryRunner.query(
|
|
153
|
+
`DROP INDEX "public"."IDX_3dc4e1c367eab9fd36b7983e44"`,
|
|
154
|
+
);
|
|
155
|
+
await queryRunner.query(
|
|
156
|
+
`DROP INDEX "public"."IDX_0c24badba9b152d08700f7d8aa"`,
|
|
157
|
+
);
|
|
158
|
+
await queryRunner.query(
|
|
159
|
+
`ALTER TABLE "UserNotificationSetting" DROP COLUMN "alertByMicrosoftTeams"`,
|
|
160
|
+
);
|
|
161
|
+
await queryRunner.query(
|
|
162
|
+
`ALTER TABLE "UserNotificationSetting" DROP COLUMN "alertBySlack"`,
|
|
163
|
+
);
|
|
164
|
+
await queryRunner.query(
|
|
165
|
+
`ALTER TABLE "UserOnCallLogTimeline" DROP COLUMN "userMicrosoftTeamsId"`,
|
|
166
|
+
);
|
|
167
|
+
await queryRunner.query(
|
|
168
|
+
`ALTER TABLE "UserOnCallLogTimeline" DROP COLUMN "userSlackId"`,
|
|
169
|
+
);
|
|
170
|
+
await queryRunner.query(
|
|
171
|
+
`ALTER TABLE "UserNotificationRule" DROP COLUMN "userMicrosoftTeamsId"`,
|
|
172
|
+
);
|
|
173
|
+
await queryRunner.query(
|
|
174
|
+
`ALTER TABLE "UserNotificationRule" DROP COLUMN "userSlackId"`,
|
|
175
|
+
);
|
|
176
|
+
await queryRunner.query(
|
|
177
|
+
`DROP INDEX "public"."IDX_e4405f9dacd3d1e3c363e8dbd3"`,
|
|
178
|
+
);
|
|
179
|
+
await queryRunner.query(
|
|
180
|
+
`DROP INDEX "public"."IDX_a746ef4fd29b03ac5abe8f4e4c"`,
|
|
181
|
+
);
|
|
182
|
+
await queryRunner.query(
|
|
183
|
+
`DROP INDEX "public"."IDX_cebf1edfa5f30a7e597633bddf"`,
|
|
184
|
+
);
|
|
185
|
+
await queryRunner.query(`DROP TABLE "UserMicrosoftTeams"`);
|
|
186
|
+
await queryRunner.query(
|
|
187
|
+
`DROP INDEX "public"."IDX_9c8fa391e949f53f670dabe222"`,
|
|
188
|
+
);
|
|
189
|
+
await queryRunner.query(
|
|
190
|
+
`DROP INDEX "public"."IDX_abe4265455b18cd43a94bb84ed"`,
|
|
191
|
+
);
|
|
192
|
+
await queryRunner.query(
|
|
193
|
+
`DROP INDEX "public"."IDX_d5dd2503bf422c6a19946216e1"`,
|
|
194
|
+
);
|
|
195
|
+
await queryRunner.query(`DROP TABLE "UserSlack"`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -540,6 +540,10 @@ import { AddLlmModelPrice1788300000000 } from "./1788300000000-AddLlmModelPrice"
|
|
|
540
540
|
import { AddMarketingConversionAttribution1788400000000 } from "./1788400000000-AddMarketingConversionAttribution";
|
|
541
541
|
import { RemoveLlmCostBudgetAlertColumns1788500000000 } from "./1788500000000-RemoveLlmCostBudgetAlertColumns";
|
|
542
542
|
import { AddDetectionRuleIncidentColumns1788600000000 } from "./1788600000000-AddDetectionRuleIncidentColumns";
|
|
543
|
+
import { RemoveMarketingConversionUploadState1788700000000 } from "./1788700000000-RemoveMarketingConversionUploadState";
|
|
544
|
+
import { DropMarketingConversionAddEnterpriseLicenseEmail1788800000000 } from "./1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail";
|
|
545
|
+
import { RedactStoredMonitorIngestSecrets1788900000000 } from "./1788900000000-RedactStoredMonitorIngestSecrets";
|
|
546
|
+
import { AddUserSlackAndMicrosoftTeams1789000000000 } from "./1789000000000-AddUserSlackAndMicrosoftTeams";
|
|
543
547
|
import { MigrationName1787142779538 } from "./1787142779538-MigrationName";
|
|
544
548
|
import { MigrationName1787156982416 } from "./1787156982416-MigrationName";
|
|
545
549
|
|
|
@@ -1088,4 +1092,8 @@ export default [
|
|
|
1088
1092
|
AddMarketingConversionAttribution1788400000000,
|
|
1089
1093
|
RemoveLlmCostBudgetAlertColumns1788500000000,
|
|
1090
1094
|
AddDetectionRuleIncidentColumns1788600000000,
|
|
1095
|
+
RemoveMarketingConversionUploadState1788700000000,
|
|
1096
|
+
DropMarketingConversionAddEnterpriseLicenseEmail1788800000000,
|
|
1097
|
+
RedactStoredMonitorIngestSecrets1788900000000,
|
|
1098
|
+
AddUserSlackAndMicrosoftTeams1789000000000,
|
|
1091
1099
|
];
|
|
@@ -17,6 +17,13 @@ export enum QueueName {
|
|
|
17
17
|
Worker = "Worker",
|
|
18
18
|
Telemetry = "Telemetry",
|
|
19
19
|
Runbook = "Runbook",
|
|
20
|
+
/*
|
|
21
|
+
* Outbound marketing conversion webhooks. Data-carrying (the job holds the
|
|
22
|
+
* whole event), unlike Worker, which looks its function up by name. Nothing
|
|
23
|
+
* stores these events, so this queue is the only thing that survives a
|
|
24
|
+
* receiver being briefly unreachable.
|
|
25
|
+
*/
|
|
26
|
+
MarketingEvent = "MarketingEvent",
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
export type QueueJob = Job;
|
|
@@ -1,10 +1,70 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import EnterpriseLicense from "../../Models/DatabaseModels/EnterpriseLicense";
|
|
3
|
+
import MarketingEventUtil from "../Utils/Marketing/MarketingEventUtil";
|
|
4
|
+
import { MarketingEventType } from "../../Types/Marketing/MarketingEvent";
|
|
5
|
+
import { OnCreate } from "../Types/Database/Hooks";
|
|
6
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
3
7
|
|
|
4
8
|
export class Service extends DatabaseService<EnterpriseLicense> {
|
|
5
9
|
public constructor() {
|
|
6
10
|
super(EnterpriseLicense);
|
|
7
11
|
}
|
|
12
|
+
|
|
13
|
+
@CaptureSpan()
|
|
14
|
+
protected override async onCreateSuccess(
|
|
15
|
+
_onCreate: OnCreate<EnterpriseLicense>,
|
|
16
|
+
createdItem: EnterpriseLicense,
|
|
17
|
+
): Promise<EnterpriseLicense> {
|
|
18
|
+
/*
|
|
19
|
+
* The outbound enterprise_license_issued conversion.
|
|
20
|
+
*
|
|
21
|
+
* This is where sales-led revenue enters the funnel. Everything else
|
|
22
|
+
* OneUptime emits is self-serve and knows its own value from the plan
|
|
23
|
+
* table; an enterprise contract is negotiated, so annualContractValue is
|
|
24
|
+
* the only place the number exists at all.
|
|
25
|
+
*
|
|
26
|
+
* Emitted even with no email and no ACV. A licence issued without either
|
|
27
|
+
* is still a licence issued, and a receiver that sees the event can chase
|
|
28
|
+
* the missing detail — one that never sees it cannot. The two nulls are
|
|
29
|
+
* reported honestly rather than defaulted to zero, which would quietly
|
|
30
|
+
* drag reported contract value down.
|
|
31
|
+
*/
|
|
32
|
+
MarketingEventUtil.emitInBackground(
|
|
33
|
+
MarketingEventUtil.buildEvent({
|
|
34
|
+
eventType: MarketingEventType.EnterpriseLicenseIssued,
|
|
35
|
+
eventId: `${MarketingEventType.EnterpriseLicenseIssued}:${createdItem.id?.toString()}`,
|
|
36
|
+
occurredAt: createdItem.createdAt || new Date(),
|
|
37
|
+
email: createdItem.email?.toString(),
|
|
38
|
+
/*
|
|
39
|
+
* No attribution source. A licence row is typed in by a human and
|
|
40
|
+
* carries no session, so its campaign is whatever the meeting_booked
|
|
41
|
+
* sharing its email carried — the join the receiver makes on
|
|
42
|
+
* emailHash, not something OneUptime can restate here.
|
|
43
|
+
*/
|
|
44
|
+
data: {
|
|
45
|
+
enterpriseLicenseId: createdItem.id?.toString() || "",
|
|
46
|
+
companyName: createdItem.companyName || "",
|
|
47
|
+
annualContractValueInUSD:
|
|
48
|
+
createdItem.annualContractValue === undefined ||
|
|
49
|
+
createdItem.annualContractValue === null
|
|
50
|
+
? null
|
|
51
|
+
: createdItem.annualContractValue,
|
|
52
|
+
currency: "USD",
|
|
53
|
+
isEvaluationLicense: Boolean(createdItem.isEvaluationLicense),
|
|
54
|
+
userLimit:
|
|
55
|
+
createdItem.userLimit === undefined ||
|
|
56
|
+
createdItem.userLimit === null
|
|
57
|
+
? null
|
|
58
|
+
: createdItem.userLimit,
|
|
59
|
+
expiresAt: createdItem.expiresAt
|
|
60
|
+
? createdItem.expiresAt.toISOString()
|
|
61
|
+
: null,
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return createdItem;
|
|
67
|
+
}
|
|
8
68
|
}
|
|
9
69
|
|
|
10
70
|
export default new Service();
|
package/Server/Services/Index.ts
CHANGED
|
@@ -145,7 +145,6 @@ import GlobalOidcProjectService from "./GlobalOidcProjectService";
|
|
|
145
145
|
import PromoCodeService from "./PromoCodeService";
|
|
146
146
|
import EnterpriseLicenseService from "./EnterpriseLicenseService";
|
|
147
147
|
import EnterpriseLicenseInstanceService from "./EnterpriseLicenseInstanceService";
|
|
148
|
-
import MarketingConversionService from "./MarketingConversionService";
|
|
149
148
|
import OpenSourceDeploymentService from "./OpenSourceDeploymentService";
|
|
150
149
|
import RecommendationDismissalService from "./RecommendationDismissalService";
|
|
151
150
|
import ResellerPlanService from "./ResellerPlanService";
|
|
@@ -213,6 +212,8 @@ import UserSmsService from "./UserSmsService";
|
|
|
213
212
|
import UserIncomingCallNumberService from "./UserIncomingCallNumberService";
|
|
214
213
|
import UserWhatsAppService from "./UserWhatsAppService";
|
|
215
214
|
import UserTelegramService from "./UserTelegramService";
|
|
215
|
+
import UserSlackService from "./UserSlackService";
|
|
216
|
+
import UserMicrosoftTeamsService from "./UserMicrosoftTeamsService";
|
|
216
217
|
import WorkflowLogService from "./WorkflowLogService";
|
|
217
218
|
// Workflows.
|
|
218
219
|
import WorkflowService from "./WorkflowService";
|
|
@@ -292,6 +293,7 @@ import WorkspaceSettingService from "./WorkspaceSettingService";
|
|
|
292
293
|
import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
|
|
293
294
|
import WorkspaceNotificationLogService from "./WorkspaceNotificationLogService";
|
|
294
295
|
import WorkspaceNotificationSummaryService from "./WorkspaceNotificationSummaryService";
|
|
296
|
+
import WorkspaceUserNotificationService from "./WorkspaceUserNotificationService";
|
|
295
297
|
import OnCallDutyPolicyUserOverrideService from "./OnCallDutyPolicyUserOverrideService";
|
|
296
298
|
|
|
297
299
|
import MonitorLogService from "./MonitorLogService";
|
|
@@ -309,7 +311,6 @@ const services: Array<BaseService> = [
|
|
|
309
311
|
PromoCodeService,
|
|
310
312
|
EnterpriseLicenseService,
|
|
311
313
|
EnterpriseLicenseInstanceService,
|
|
312
|
-
MarketingConversionService,
|
|
313
314
|
OpenSourceDeploymentService,
|
|
314
315
|
|
|
315
316
|
ResellerService,
|
|
@@ -490,6 +491,8 @@ const services: Array<BaseService> = [
|
|
|
490
491
|
UserIncomingCallNumberService,
|
|
491
492
|
UserWhatsAppService,
|
|
492
493
|
UserTelegramService,
|
|
494
|
+
UserSlackService,
|
|
495
|
+
UserMicrosoftTeamsService,
|
|
493
496
|
UserTotpAuthService,
|
|
494
497
|
UserWebAuthnService,
|
|
495
498
|
|
|
@@ -587,6 +590,7 @@ const services: Array<BaseService> = [
|
|
|
587
590
|
WorkspaceNotificationRuleService,
|
|
588
591
|
WorkspaceNotificationLogService,
|
|
589
592
|
WorkspaceNotificationSummaryService,
|
|
593
|
+
WorkspaceUserNotificationService,
|
|
590
594
|
|
|
591
595
|
ProjectSCIMLogService,
|
|
592
596
|
StatusPageSCIMLogService,
|
|
@@ -57,24 +57,40 @@ export class Service extends DatabaseService<Model> {
|
|
|
57
57
|
const incidentRunMembership: string = `EXISTS (SELECT 1 FROM "AIRun" AS "run" WHERE "run"."_id" = "log"."aiRunId" AND "run"."triggeredByIncidentId" IS NOT NULL AND "run"."triggeredByAlertId" IS NULL)`;
|
|
58
58
|
const alertRunMembership: string = `EXISTS (SELECT 1 FROM "AIRun" AS "run" WHERE "run"."_id" = "log"."aiRunId" AND "run"."triggeredByIncidentId" IS NULL AND "run"."triggeredByAlertId" IS NOT NULL)`;
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
/*
|
|
61
|
+
* Placeholders and bindings are built together, per branch, because
|
|
62
|
+
* PostgreSQL derives a prepared statement's parameter count from the
|
|
63
|
+
* HIGHEST $n present in the text — not from what the driver sends. A
|
|
64
|
+
* branch that binds an argument it never references is rejected outright
|
|
65
|
+
* at Bind (bind message supplies 5 parameters, but prepared statement
|
|
66
|
+
* requires 4), and a branch that skips a placeholder is rejected at Parse
|
|
67
|
+
* (could not determine data type of parameter $4). Both are runtime-only
|
|
68
|
+
* failures no compiler catches, so the parameter array is grown next to
|
|
69
|
+
* the clause that reads it and never assembled apart from it.
|
|
70
|
+
*/
|
|
71
|
+
const params: Array<unknown> = [
|
|
72
|
+
data.projectId.toString(), // $1
|
|
73
|
+
data.since, // $2
|
|
74
|
+
data.features, // $3
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
let subjectClause: string;
|
|
61
78
|
|
|
62
79
|
if (data.incidentId) {
|
|
80
|
+
params.push(legacyIncidentFeatures); // $4
|
|
63
81
|
subjectClause = `AND (("log"."incidentId" IS NOT NULL AND "log"."alertId" IS NULL) OR ("log"."incidentId" IS NULL AND "log"."alertId" IS NULL AND (("log"."feature" = ANY($4)) OR ${incidentRunMembership})))`;
|
|
64
82
|
} else if (data.alertId) {
|
|
65
|
-
|
|
83
|
+
params.push(legacyAlertFeatures); // $4
|
|
84
|
+
subjectClause = `AND (("log"."incidentId" IS NULL AND "log"."alertId" IS NOT NULL) OR ("log"."incidentId" IS NULL AND "log"."alertId" IS NULL AND (("log"."feature" = ANY($4)) OR ${alertRunMembership})))`;
|
|
85
|
+
} else {
|
|
86
|
+
params.push(legacyIncidentFeatures, legacyAlertFeatures); // $4, $5
|
|
87
|
+
subjectClause = `AND "log"."incidentId" IS NULL AND "log"."alertId" IS NULL AND NOT ("log"."feature" = ANY($4)) AND NOT ("log"."feature" = ANY($5)) AND NOT (${incidentRunMembership}) AND NOT (${alertRunMembership})`;
|
|
66
88
|
}
|
|
67
89
|
|
|
68
90
|
const rows: Array<{ total: string | number | null }> =
|
|
69
91
|
await this.getRepository().manager.query(
|
|
70
92
|
`SELECT COALESCE(SUM("log"."totalTokens"), 0) AS "total" FROM "LlmLog" AS "log" WHERE "log"."projectId" = $1 AND "log"."createdAt" >= $2 AND "log"."feature" = ANY($3) ${subjectClause} AND "log"."deletedAt" IS NULL`,
|
|
71
|
-
|
|
72
|
-
data.projectId.toString(),
|
|
73
|
-
data.since,
|
|
74
|
-
data.features,
|
|
75
|
-
legacyIncidentFeatures,
|
|
76
|
-
legacyAlertFeatures,
|
|
77
|
-
],
|
|
93
|
+
params,
|
|
78
94
|
);
|
|
79
95
|
|
|
80
96
|
return Number(rows[0]?.total || 0);
|
|
@@ -16,6 +16,8 @@ import UserPushService from "./UserPushService";
|
|
|
16
16
|
import UserService from "./UserService";
|
|
17
17
|
import UserSmsService from "./UserSmsService";
|
|
18
18
|
import UserTelegramService from "./UserTelegramService";
|
|
19
|
+
import UserSlackService from "./UserSlackService";
|
|
20
|
+
import UserMicrosoftTeamsService from "./UserMicrosoftTeamsService";
|
|
19
21
|
import UserWebhookService from "./UserWebhookService";
|
|
20
22
|
import UserWhatsAppService from "./UserWhatsAppService";
|
|
21
23
|
import InMemoryTTLCache from "../Infrastructure/InMemoryTTLCache";
|
|
@@ -51,6 +53,8 @@ import UserNotificationRule from "../../Models/DatabaseModels/UserNotificationRu
|
|
|
51
53
|
import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
52
54
|
import UserSMS from "../../Models/DatabaseModels/UserSMS";
|
|
53
55
|
import UserTelegram from "../../Models/DatabaseModels/UserTelegram";
|
|
56
|
+
import UserSlack from "../../Models/DatabaseModels/UserSlack";
|
|
57
|
+
import UserMicrosoftTeams from "../../Models/DatabaseModels/UserMicrosoftTeams";
|
|
54
58
|
import UserWebhook from "../../Models/DatabaseModels/UserWebhook";
|
|
55
59
|
import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
|
|
56
60
|
|
|
@@ -116,7 +120,7 @@ export enum ResponderSource {
|
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
/**
|
|
119
|
-
* The
|
|
123
|
+
* The nine channels a page can be delivered on. These strings are the same literals the
|
|
120
124
|
* fallback uses for `channelsUsed` (UserNotificationRuleService.chooseFallbackChannels),
|
|
121
125
|
* deliberately: an operator reading "notified via fallback (Push, Email)" in an execution
|
|
122
126
|
* log and "Push, Email" in the readiness table must not have to translate between two
|
|
@@ -129,6 +133,8 @@ export enum ReadinessMethodType {
|
|
|
129
133
|
Call = "Call",
|
|
130
134
|
WhatsApp = "WhatsApp",
|
|
131
135
|
Telegram = "Telegram",
|
|
136
|
+
Slack = "Slack",
|
|
137
|
+
MicrosoftTeams = "Microsoft Teams",
|
|
132
138
|
Webhook = "Webhook",
|
|
133
139
|
}
|
|
134
140
|
|
|
@@ -436,6 +442,8 @@ const RULE_TYPE_SCOPES: Array<RuleTypeScope> = [
|
|
|
436
442
|
const METHOD_DISPLAY_ORDER: Array<ReadinessMethodType> = [
|
|
437
443
|
ReadinessMethodType.Push,
|
|
438
444
|
ReadinessMethodType.Email,
|
|
445
|
+
ReadinessMethodType.Slack,
|
|
446
|
+
ReadinessMethodType.MicrosoftTeams,
|
|
439
447
|
ReadinessMethodType.SMS,
|
|
440
448
|
ReadinessMethodType.Call,
|
|
441
449
|
ReadinessMethodType.WhatsApp,
|
|
@@ -2194,6 +2202,74 @@ export default class OnCallReadinessService {
|
|
|
2194
2202
|
},
|
|
2195
2203
|
});
|
|
2196
2204
|
|
|
2205
|
+
await this.readEveryPage<UserSlack>({
|
|
2206
|
+
description: "Slack notification methods",
|
|
2207
|
+
projectId: projectId,
|
|
2208
|
+
completeness: completeness,
|
|
2209
|
+
service: UserSlackService,
|
|
2210
|
+
query: {
|
|
2211
|
+
projectId: projectId,
|
|
2212
|
+
userId: new Includes(userIds),
|
|
2213
|
+
},
|
|
2214
|
+
/*
|
|
2215
|
+
* The username only — never slackUserId. The member id is the
|
|
2216
|
+
* addressable target the bot sends to; the username is the human-facing
|
|
2217
|
+
* label, and it is the one a user can recognise as theirs.
|
|
2218
|
+
*/
|
|
2219
|
+
select: {
|
|
2220
|
+
_id: true,
|
|
2221
|
+
userId: true,
|
|
2222
|
+
slackUserName: true,
|
|
2223
|
+
isVerified: true,
|
|
2224
|
+
},
|
|
2225
|
+
consumePage: (rows: Array<UserSlack>): void => {
|
|
2226
|
+
for (const row of rows) {
|
|
2227
|
+
addMethod(row, {
|
|
2228
|
+
methodType: ReadinessMethodType.Slack,
|
|
2229
|
+
maskedIdentifier: maskIdentifier(
|
|
2230
|
+
row.slackUserName,
|
|
2231
|
+
MaskedIdentifierKind.Handle,
|
|
2232
|
+
),
|
|
2233
|
+
isVerified: Boolean(row.isVerified),
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
},
|
|
2237
|
+
});
|
|
2238
|
+
|
|
2239
|
+
await this.readEveryPage<UserMicrosoftTeams>({
|
|
2240
|
+
description: "Microsoft Teams notification methods",
|
|
2241
|
+
projectId: projectId,
|
|
2242
|
+
completeness: completeness,
|
|
2243
|
+
service: UserMicrosoftTeamsService,
|
|
2244
|
+
query: {
|
|
2245
|
+
projectId: projectId,
|
|
2246
|
+
userId: new Includes(userIds),
|
|
2247
|
+
},
|
|
2248
|
+
/*
|
|
2249
|
+
* The display name only — never microsoftTeamsUserId. The Entra id is
|
|
2250
|
+
* the addressable target the bot sends to; the display name is the
|
|
2251
|
+
* human-facing label, and it is the one a user can recognise as theirs.
|
|
2252
|
+
*/
|
|
2253
|
+
select: {
|
|
2254
|
+
_id: true,
|
|
2255
|
+
userId: true,
|
|
2256
|
+
microsoftTeamsUserName: true,
|
|
2257
|
+
isVerified: true,
|
|
2258
|
+
},
|
|
2259
|
+
consumePage: (rows: Array<UserMicrosoftTeams>): void => {
|
|
2260
|
+
for (const row of rows) {
|
|
2261
|
+
addMethod(row, {
|
|
2262
|
+
methodType: ReadinessMethodType.MicrosoftTeams,
|
|
2263
|
+
maskedIdentifier: maskIdentifier(
|
|
2264
|
+
row.microsoftTeamsUserName,
|
|
2265
|
+
MaskedIdentifierKind.Handle,
|
|
2266
|
+
),
|
|
2267
|
+
isVerified: Boolean(row.isVerified),
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
},
|
|
2271
|
+
});
|
|
2272
|
+
|
|
2197
2273
|
await this.readEveryPage<UserWebhook>({
|
|
2198
2274
|
description: "webhook notification methods",
|
|
2199
2275
|
projectId: projectId,
|
|
@@ -2677,7 +2753,7 @@ export default class OnCallReadinessService {
|
|
|
2677
2753
|
* the real thing rather than a hopeful "some verified method".
|
|
2678
2754
|
*
|
|
2679
2755
|
* This mirrors UserNotificationRuleService.chooseFallbackChannels exactly, including
|
|
2680
|
-
* the project switches: zero-cost channels first and
|
|
2756
|
+
* the project switches: zero-cost channels first and ALL of them if present, then one
|
|
2681
2757
|
* paid channel in escalating-intrusiveness order, then webhook. If that function's
|
|
2682
2758
|
* order ever changes, this one has to change with it — a readiness surface promising
|
|
2683
2759
|
* "falls back to SMS" for a project that has SMS switched off is worse than saying
|
|
@@ -2709,6 +2785,14 @@ export default class OnCallReadinessService {
|
|
|
2709
2785
|
zeroCost.push(ReadinessMethodType.Email);
|
|
2710
2786
|
}
|
|
2711
2787
|
|
|
2788
|
+
if (has(ReadinessMethodType.Slack)) {
|
|
2789
|
+
zeroCost.push(ReadinessMethodType.Slack);
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
if (has(ReadinessMethodType.MicrosoftTeams)) {
|
|
2793
|
+
zeroCost.push(ReadinessMethodType.MicrosoftTeams);
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2712
2796
|
if (zeroCost.length > 0) {
|
|
2713
2797
|
return zeroCost;
|
|
2714
2798
|
}
|