@oneuptime/common 7.0.3827 → 7.0.3840
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/GlobalConfig.ts +22 -4
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.ts +48 -0
- package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +502 -0
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +35 -4
- package/Models/DatabaseModels/UserOnCallLog.ts +43 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741904597606-MigrationName.ts +69 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741908200702-MigrationName.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741955609393-MigrationName.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741955752685-MigrationName.ts +23 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741957080431-MigrationName.ts +23 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741959216297-MigrationName.ts +23 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Services/CallService.ts +4 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +90 -3
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +17 -1
- package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +77 -0
- package/Server/Services/ProjectCallSMSConfigService.ts +12 -2
- package/Server/Services/SmsService.ts +4 -1
- package/Server/Services/StatusPageSubscriberService.ts +4 -2
- package/Server/Services/UserNotificationRuleService.ts +5 -0
- package/Types/CallAndSMS/TwilioConfig.ts +2 -1
- package/Types/Permission.ts +38 -0
- package/Types/Phone.ts +61 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -5
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js +49 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +516 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +38 -5
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +44 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741904597606-MigrationName.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741904597606-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741908200702-MigrationName.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741908200702-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741955609393-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741955609393-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741955752685-MigrationName.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741955752685-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741957080431-MigrationName.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741957080431-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741959216297-MigrationName.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741959216297-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/CallService.js +3 -2
- package/build/dist/Server/Services/CallService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +59 -3
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +14 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +49 -0
- package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -0
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js +11 -2
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
- package/build/dist/Server/Services/SmsService.js +3 -2
- package/build/dist/Server/Services/SmsService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -2
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +3 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Types/Permission.js +32 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Phone.js +32 -0
- package/build/dist/Types/Phone.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741904597606 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741904597606";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`CREATE TABLE "OnCallDutyPolicyUserOverride" ("_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, "onCallDutyPolicyId" uuid, "name" character varying(100) NOT NULL, "description" character varying(500), "createdByUserId" uuid, "overrideUserId" uuid NOT NULL, "routeAlertsToUserId" uuid NOT NULL, "startsAt" TIMESTAMP WITH TIME ZONE NOT NULL, "endsAt" TIMESTAMP WITH TIME ZONE NOT NULL, "deletedByUserId" uuid, CONSTRAINT "PK_41b216c8e71d15182fe67b75fec" PRIMARY KEY ("_id"))`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`CREATE INDEX "IDX_75b4e0f9bc53be5cdaa55b2936" ON "OnCallDutyPolicyUserOverride" ("projectId") `,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`CREATE INDEX "IDX_6a13404edca5d177b3ad539995" ON "OnCallDutyPolicyUserOverride" ("onCallDutyPolicyId") `,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`CREATE INDEX "IDX_b0bdac6c10d7ed30e696aded2c" ON "OnCallDutyPolicyUserOverride" ("name") `,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_75b4e0f9bc53be5cdaa55b29361" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
21
|
+
);
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_6a13404edca5d177b3ad539995d" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_c21b1df32e40e739a66d638a3c7" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_4b3f696aaaf327b245ebeb3d146" FOREIGN KEY ("overrideUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_8771068ec4c16763a7ff796895d" FOREIGN KEY ("routeAlertsToUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_810a8cd7f838a8e141fd750a9d5" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
40
|
+
await queryRunner.query(
|
|
41
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_810a8cd7f838a8e141fd750a9d5"`,
|
|
42
|
+
);
|
|
43
|
+
await queryRunner.query(
|
|
44
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_8771068ec4c16763a7ff796895d"`,
|
|
45
|
+
);
|
|
46
|
+
await queryRunner.query(
|
|
47
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_4b3f696aaaf327b245ebeb3d146"`,
|
|
48
|
+
);
|
|
49
|
+
await queryRunner.query(
|
|
50
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_c21b1df32e40e739a66d638a3c7"`,
|
|
51
|
+
);
|
|
52
|
+
await queryRunner.query(
|
|
53
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_6a13404edca5d177b3ad539995d"`,
|
|
54
|
+
);
|
|
55
|
+
await queryRunner.query(
|
|
56
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_75b4e0f9bc53be5cdaa55b29361"`,
|
|
57
|
+
);
|
|
58
|
+
await queryRunner.query(
|
|
59
|
+
`DROP INDEX "public"."IDX_b0bdac6c10d7ed30e696aded2c"`,
|
|
60
|
+
);
|
|
61
|
+
await queryRunner.query(
|
|
62
|
+
`DROP INDEX "public"."IDX_6a13404edca5d177b3ad539995"`,
|
|
63
|
+
);
|
|
64
|
+
await queryRunner.query(
|
|
65
|
+
`DROP INDEX "public"."IDX_75b4e0f9bc53be5cdaa55b2936"`,
|
|
66
|
+
);
|
|
67
|
+
await queryRunner.query(`DROP TABLE "OnCallDutyPolicyUserOverride"`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741908200702 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741908200702";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`DROP INDEX "public"."IDX_b0bdac6c10d7ed30e696aded2c"`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP COLUMN "name"`,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" DROP COLUMN "description"`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD "description" character varying(500)`,
|
|
21
|
+
);
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "OnCallDutyPolicyUserOverride" ADD "name" character varying(100) NOT NULL`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`CREATE INDEX "IDX_b0bdac6c10d7ed30e696aded2c" ON "OnCallDutyPolicyUserOverride" ("name") `,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741955609393 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741955609393";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "GlobalConfig" RENAME COLUMN "twilioPhoneNumber" TO "twilioPrimaryPhoneNumber"`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "ProjectCallSMSConfig" RENAME COLUMN "twilioPhoneNumber" TO "twilioPrimaryPhoneNumber"`,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "GlobalConfig" ADD "twilioSecondaryPhoneNumbers" character varying(500)`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "ProjectCallSMSConfig" ADD "twilioSecondaryPhoneNumbers" character varying(500)`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "ProjectCallSMSConfig" DROP COLUMN "twilioSecondaryPhoneNumbers"`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "GlobalConfig" DROP COLUMN "twilioSecondaryPhoneNumbers"`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "ProjectCallSMSConfig" RENAME COLUMN "twilioPrimaryPhoneNumber" TO "twilioPhoneNumber"`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "GlobalConfig" RENAME COLUMN "twilioPrimaryPhoneNumber" TO "twilioPhoneNumber"`,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741955752685 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741955752685";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "GlobalConfig" DROP CONSTRAINT "UQ_c223b66a0ca2fa8095cb7a6c7cc"`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "ProjectCallSMSConfig" DROP CONSTRAINT "UQ_50235223d7fd7b0c27063bfb08e"`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "ProjectCallSMSConfig" ADD CONSTRAINT "UQ_50235223d7fd7b0c27063bfb08e" UNIQUE ("twilioPrimaryPhoneNumber")`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "GlobalConfig" ADD CONSTRAINT "UQ_c223b66a0ca2fa8095cb7a6c7cc" UNIQUE ("twilioPrimaryPhoneNumber")`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741957080431 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741957080431";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "UserOnCallLog" ADD "overridedByUserId" uuid`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "UserOnCallLog" ADD CONSTRAINT "FK_702b8c74c8f0d7fb220bc407776" FOREIGN KEY ("overridedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "UserOnCallLog" DROP CONSTRAINT "FK_702b8c74c8f0d7fb220bc407776"`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "UserOnCallLog" DROP COLUMN "overridedByUserId"`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741959216297 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741959216297";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "OnCallDutyPolicyExecutionLogTimeline" ADD "overridedByUserId" uuid`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "OnCallDutyPolicyExecutionLogTimeline" ADD CONSTRAINT "FK_356ab0badd7e70f4d25045dcbf3" FOREIGN KEY ("overridedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "OnCallDutyPolicyExecutionLogTimeline" DROP CONSTRAINT "FK_356ab0badd7e70f4d25045dcbf3"`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "OnCallDutyPolicyExecutionLogTimeline" DROP COLUMN "overridedByUserId"`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -112,6 +112,12 @@ import { MigrationName1740597525803 } from "./1740597525803-MigrationName";
|
|
|
112
112
|
import { MigrationName1740598793630 } from "./1740598793630-MigrationName";
|
|
113
113
|
import { MigrationName1741031019972 } from "./1741031019972-MigrationName";
|
|
114
114
|
import { MigrationName1741209339971 } from "./1741209339971-MigrationName";
|
|
115
|
+
import { MigrationName1741904597606 } from "./1741904597606-MigrationName";
|
|
116
|
+
import { MigrationName1741908200702 } from "./1741908200702-MigrationName";
|
|
117
|
+
import { MigrationName1741955609393 } from "./1741955609393-MigrationName";
|
|
118
|
+
import { MigrationName1741955752685 } from "./1741955752685-MigrationName";
|
|
119
|
+
import { MigrationName1741957080431 } from "./1741957080431-MigrationName";
|
|
120
|
+
import { MigrationName1741959216297 } from "./1741959216297-MigrationName";
|
|
115
121
|
|
|
116
122
|
export default [
|
|
117
123
|
InitialMigration,
|
|
@@ -228,4 +234,10 @@ export default [
|
|
|
228
234
|
MigrationName1740598793630,
|
|
229
235
|
MigrationName1741031019972,
|
|
230
236
|
MigrationName1741209339971,
|
|
237
|
+
MigrationName1741904597606,
|
|
238
|
+
MigrationName1741908200702,
|
|
239
|
+
MigrationName1741955609393,
|
|
240
|
+
MigrationName1741955752685,
|
|
241
|
+
MigrationName1741957080431,
|
|
242
|
+
MigrationName1741959216297,
|
|
231
243
|
];
|
|
@@ -35,7 +35,10 @@ export class CallService extends BaseService {
|
|
|
35
35
|
? {
|
|
36
36
|
accountSid: options.customTwilioConfig.accountSid!,
|
|
37
37
|
authToken: options.customTwilioConfig.authToken!,
|
|
38
|
-
|
|
38
|
+
primaryPhoneNumber:
|
|
39
|
+
options.customTwilioConfig.primaryPhoneNumber.toString(),
|
|
40
|
+
secondaryPhoneNumbers:
|
|
41
|
+
options.customTwilioConfig.secondaryPhoneNumbers?.toString(),
|
|
39
42
|
}
|
|
40
43
|
: undefined,
|
|
41
44
|
};
|
package/Server/Services/Index.ts
CHANGED
|
@@ -156,6 +156,7 @@ import WorkspaceProjectAuthTokenService from "./WorkspaceProjectAuthTokenService
|
|
|
156
156
|
import WorkspaceUserAuthTokenService from "./WorkspaceUserAuthTokenService";
|
|
157
157
|
import WorkspaceSettingService from "./WorkspaceSettingService";
|
|
158
158
|
import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
|
|
159
|
+
import OnCallDutyPolicyUserOverrideService from "./OnCallDutyPolicyUserOverrideService";
|
|
159
160
|
|
|
160
161
|
const services: Array<BaseService> = [
|
|
161
162
|
AcmeCertificateService,
|
|
@@ -218,6 +219,7 @@ const services: Array<BaseService> = [
|
|
|
218
219
|
OnCallDutyPolicyExecutionLogService,
|
|
219
220
|
OnCallDutyPolicyExecutionLogTimelineService,
|
|
220
221
|
OnCallDutyPolicyService,
|
|
222
|
+
OnCallDutyPolicyUserOverrideService,
|
|
221
223
|
|
|
222
224
|
ProjectService,
|
|
223
225
|
ProjectSmtpConfigService,
|
|
@@ -31,8 +31,76 @@ import OnCallDutyPolicyEscalationRuleUser from "Common/Models/DatabaseModels/OnC
|
|
|
31
31
|
import OnCallDutyPolicyExecutionLogTimeline from "Common/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline";
|
|
32
32
|
import User from "Common/Models/DatabaseModels/User";
|
|
33
33
|
import logger from "../Utils/Logger";
|
|
34
|
+
import OnCallDutyPolicyUserOverride from "../../Models/DatabaseModels/OnCallDutyPolicyUserOverride";
|
|
35
|
+
import OnCallDutyPolicyUserOverrideService from "./OnCallDutyPolicyUserOverrideService";
|
|
34
36
|
|
|
35
37
|
export class Service extends DatabaseService<Model> {
|
|
38
|
+
public async getRouteAlertToUserId(data: {
|
|
39
|
+
userId: ObjectID;
|
|
40
|
+
onCallDutyPolicyId: ObjectID;
|
|
41
|
+
projectId: ObjectID;
|
|
42
|
+
}): Promise<ObjectID | null> {
|
|
43
|
+
logger.debug(
|
|
44
|
+
`Getting route alert to user id for userId: ${data.userId.toString()}`,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const currentDate: Date = OneUptimeDate.getCurrentDate();
|
|
48
|
+
|
|
49
|
+
const alertRoutedTo: Array<OnCallDutyPolicyUserOverride> =
|
|
50
|
+
await OnCallDutyPolicyUserOverrideService.findBy({
|
|
51
|
+
query: {
|
|
52
|
+
overrideUserId: data.userId,
|
|
53
|
+
onCallDutyPolicyId: QueryHelper.equalToOrNull(
|
|
54
|
+
data.onCallDutyPolicyId,
|
|
55
|
+
), // find global overrides as well. If this is null, then it will find global overrides.
|
|
56
|
+
projectId: data.projectId,
|
|
57
|
+
startsAt: QueryHelper.lessThanEqualTo(currentDate),
|
|
58
|
+
endsAt: QueryHelper.greaterThanEqualTo(currentDate),
|
|
59
|
+
},
|
|
60
|
+
props: {
|
|
61
|
+
isRoot: true,
|
|
62
|
+
},
|
|
63
|
+
limit: LIMIT_PER_PROJECT,
|
|
64
|
+
skip: 0,
|
|
65
|
+
select: {
|
|
66
|
+
routeAlertsToUserId: true,
|
|
67
|
+
onCallDutyPolicyId: true,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
logger.debug(`Found alert routed to: ${JSON.stringify(alertRoutedTo)}`);
|
|
72
|
+
|
|
73
|
+
// local override takes precedence over global override.
|
|
74
|
+
const localOverride: OnCallDutyPolicyUserOverride | undefined =
|
|
75
|
+
alertRoutedTo.find((item: OnCallDutyPolicyUserOverride) => {
|
|
76
|
+
return (
|
|
77
|
+
item.onCallDutyPolicyId?.toString() ===
|
|
78
|
+
data.onCallDutyPolicyId.toString()
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (localOverride && localOverride.routeAlertsToUserId) {
|
|
83
|
+
logger.debug(
|
|
84
|
+
`Route alert to user id found: ${localOverride.routeAlertsToUserId.toString()}`,
|
|
85
|
+
);
|
|
86
|
+
return localOverride.routeAlertsToUserId;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const globalOverride: OnCallDutyPolicyUserOverride | undefined =
|
|
90
|
+
alertRoutedTo.find((item: OnCallDutyPolicyUserOverride) => {
|
|
91
|
+
return !item.onCallDutyPolicyId;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (globalOverride && globalOverride.routeAlertsToUserId) {
|
|
95
|
+
logger.debug(
|
|
96
|
+
`Route alert to user id found: ${globalOverride.routeAlertsToUserId.toString()}`,
|
|
97
|
+
);
|
|
98
|
+
return globalOverride.routeAlertsToUserId;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
36
104
|
public async startRuleExecution(
|
|
37
105
|
ruleId: ObjectID,
|
|
38
106
|
options: {
|
|
@@ -190,13 +258,31 @@ export class Service extends DatabaseService<Model> {
|
|
|
190
258
|
): Promise<void> => {
|
|
191
259
|
// This is where user is notified.
|
|
192
260
|
|
|
261
|
+
// get route alert to user id.
|
|
262
|
+
let routeAlertToUserId: ObjectID | null = null;
|
|
263
|
+
|
|
264
|
+
if (options.onCallPolicyId) {
|
|
265
|
+
routeAlertToUserId = await this.getRouteAlertToUserId({
|
|
266
|
+
userId,
|
|
267
|
+
onCallDutyPolicyId: options.onCallPolicyId,
|
|
268
|
+
projectId: options.projectId,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const alertSentToUserId: ObjectID = routeAlertToUserId || userId;
|
|
273
|
+
|
|
193
274
|
logger.debug(
|
|
194
|
-
`Starting notification rule execution for userId: ${
|
|
275
|
+
`Starting notification rule execution for userId: ${alertSentToUserId.toString()}`,
|
|
195
276
|
);
|
|
196
277
|
let log: OnCallDutyPolicyExecutionLogTimeline = getNewLog();
|
|
197
278
|
log.statusMessage = "Sending notification to user.";
|
|
198
279
|
log.status = OnCallDutyExecutionLogTimelineStatus.Executing;
|
|
199
|
-
log.alertSentToUserId =
|
|
280
|
+
log.alertSentToUserId = alertSentToUserId;
|
|
281
|
+
|
|
282
|
+
if (routeAlertToUserId) {
|
|
283
|
+
log.overridedByUserId = userId;
|
|
284
|
+
}
|
|
285
|
+
|
|
200
286
|
if (teamId) {
|
|
201
287
|
log.userBelongsToTeamId = teamId;
|
|
202
288
|
}
|
|
@@ -213,7 +299,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
213
299
|
});
|
|
214
300
|
|
|
215
301
|
await UserNotificationRuleService.startUserNotificationRulesExecution(
|
|
216
|
-
|
|
302
|
+
alertSentToUserId,
|
|
217
303
|
{
|
|
218
304
|
userNotificationEventType: options.userNotificationEventType!,
|
|
219
305
|
triggeredByIncidentId: options.triggeredByIncidentId || undefined,
|
|
@@ -225,6 +311,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
225
311
|
onCallDutyPolicyExecutionLogTimelineId: log.id!,
|
|
226
312
|
projectId: options.projectId,
|
|
227
313
|
onCallScheduleId: scheduleId || undefined,
|
|
314
|
+
overridedByUserId: routeAlertToUserId ? userId : undefined,
|
|
228
315
|
},
|
|
229
316
|
);
|
|
230
317
|
};
|
|
@@ -104,6 +104,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
104
104
|
name: true,
|
|
105
105
|
_id: true,
|
|
106
106
|
},
|
|
107
|
+
overridedByUser: {
|
|
108
|
+
name: true,
|
|
109
|
+
_id: true,
|
|
110
|
+
},
|
|
107
111
|
},
|
|
108
112
|
props: {
|
|
109
113
|
isRoot: true,
|
|
@@ -166,7 +170,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
166
170
|
incidentOrAlertLink = `[Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByAlertId)).toString()})`;
|
|
167
171
|
}
|
|
168
172
|
|
|
169
|
-
|
|
173
|
+
let feedInfoInMarkdown: string = `**${this.getEmojiBasedOnStatus(status)} ${incidentOrAlertLink} On-Call Alert ${status} to ${await UserService.getUserMarkdownString(
|
|
170
174
|
{
|
|
171
175
|
userId: onCallDutyPolicyExecutionLogTimeline.alertSentToUserId!,
|
|
172
176
|
projectId: onCallDutyPolicyExecutionLogTimeline.projectId!,
|
|
@@ -180,6 +184,18 @@ The on-call policy **[${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.na
|
|
|
180
184
|
},
|
|
181
185
|
)} was alerted. The status of this alert is **${status}** with the message: \`${onCallDutyPolicyExecutionLogTimeline.statusMessage}\`. ${onCallDutyPolicyExecutionLogTimeline.userBelongsToTeam?.name ? "The alert was sent because the user belogs to the team **" + onCallDutyPolicyExecutionLogTimeline.userBelongsToTeam?.name + "**" : ""} ${onCallDutyPolicyExecutionLogTimeline.isAcknowledged ? "The alert was acknowledged at **" + onCallDutyPolicyExecutionLogTimeline.acknowledgedAt + "**" : ""}`;
|
|
182
186
|
|
|
187
|
+
if (onCallDutyPolicyExecutionLogTimeline.overridedByUser) {
|
|
188
|
+
feedInfoInMarkdown += `The alert was supposed to be sent to **${await UserService.getUserMarkdownString(
|
|
189
|
+
{
|
|
190
|
+
userId: onCallDutyPolicyExecutionLogTimeline.overridedByUser.id!,
|
|
191
|
+
projectId: onCallDutyPolicyExecutionLogTimeline.projectId!,
|
|
192
|
+
},
|
|
193
|
+
)}** but was routed to **${await UserService.getUserMarkdownString({
|
|
194
|
+
userId: onCallDutyPolicyExecutionLogTimeline.alertSentToUserId!,
|
|
195
|
+
projectId: onCallDutyPolicyExecutionLogTimeline.projectId!,
|
|
196
|
+
})}** instead, because of an override rule.`;
|
|
197
|
+
}
|
|
198
|
+
|
|
183
199
|
logger.debug("Feed Info in Markdown: " + feedInfoInMarkdown);
|
|
184
200
|
|
|
185
201
|
if (onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentId) {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import ObjectID from "../../Types/ObjectID";
|
|
3
|
+
import DatabaseConfig from "../DatabaseConfig";
|
|
4
|
+
import URL from "../../Types/API/URL";
|
|
5
|
+
import OnCallDutyPolicyUserOverride from "../../Models/DatabaseModels/OnCallDutyPolicyUserOverride";
|
|
6
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
7
|
+
import { OnCreate } from "../Types/Database/Hooks";
|
|
8
|
+
import OneUptimeDate from "../../Types/Date";
|
|
9
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
10
|
+
|
|
11
|
+
export class Service extends DatabaseService<OnCallDutyPolicyUserOverride> {
|
|
12
|
+
public constructor() {
|
|
13
|
+
super(OnCallDutyPolicyUserOverride);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
protected override async onBeforeCreate(
|
|
17
|
+
createBy: CreateBy<OnCallDutyPolicyUserOverride>,
|
|
18
|
+
): Promise<OnCreate<OnCallDutyPolicyUserOverride>> {
|
|
19
|
+
if (!createBy.data.startsAt || !createBy.data.endsAt) {
|
|
20
|
+
throw new BadDataException("Start time and end time are required");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// make sure start time is before end time
|
|
24
|
+
if (OneUptimeDate.isAfter(createBy.data.startsAt, createBy.data.endsAt)) {
|
|
25
|
+
throw new BadDataException("Start time must be before end time");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// make sure overrideUser and routealertsToUser are not the same
|
|
29
|
+
const overrideUserId: ObjectID | undefined | null =
|
|
30
|
+
createBy.data.overrideUserId || createBy.data.overrideUser?.id;
|
|
31
|
+
|
|
32
|
+
if (!overrideUserId) {
|
|
33
|
+
throw new BadDataException("Override user is required");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const routeAlertsToUserId: ObjectID | undefined | null =
|
|
37
|
+
createBy.data.routeAlertsToUserId || createBy.data.routeAlertsToUser?.id;
|
|
38
|
+
|
|
39
|
+
if (!routeAlertsToUserId) {
|
|
40
|
+
throw new BadDataException("Route alerts to user is required");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (overrideUserId.toString() === routeAlertsToUserId.toString()) {
|
|
44
|
+
throw new BadDataException(
|
|
45
|
+
"Override user and route alerts to user cannot be the same",
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
createBy,
|
|
51
|
+
carryForward: null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public async getOnCallDutyPolicyUserOverrideLinkInDashboard(data: {
|
|
56
|
+
projectId: ObjectID;
|
|
57
|
+
onCallDutyPolicyId?: ObjectID | undefined; // if this is null then this is a global override
|
|
58
|
+
onCallDutyPolicyUserOverrideId: ObjectID;
|
|
59
|
+
}): Promise<URL> {
|
|
60
|
+
const projectId: ObjectID = data.projectId;
|
|
61
|
+
const onCallDutyPolicyId: ObjectID | undefined = data.onCallDutyPolicyId;
|
|
62
|
+
const onCallDutyPolicyUserOverrideId: ObjectID =
|
|
63
|
+
data.onCallDutyPolicyUserOverrideId;
|
|
64
|
+
|
|
65
|
+
const dashboardUrl: URL = await DatabaseConfig.getDashboardUrl();
|
|
66
|
+
|
|
67
|
+
if (!onCallDutyPolicyId) {
|
|
68
|
+
return URL.fromString(dashboardUrl.toString()).addRoute(
|
|
69
|
+
`/${projectId.toString()}/on-call-duty/user-overrides/${onCallDutyPolicyUserOverrideId.toString()}`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return URL.fromString(dashboardUrl.toString()).addRoute(
|
|
73
|
+
`/${projectId.toString()}/on-call-duty/policies/${onCallDutyPolicyId.toString()}/user-overrides/${onCallDutyPolicyUserOverrideId.toString()}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export default new Service();
|
|
@@ -2,6 +2,7 @@ import DatabaseService from "./DatabaseService";
|
|
|
2
2
|
import TwilioConfig from "../../Types/CallAndSMS/TwilioConfig";
|
|
3
3
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
4
4
|
import Model from "Common/Models/DatabaseModels/ProjectCallSMSConfig";
|
|
5
|
+
import Phone from "../../Types/Phone";
|
|
5
6
|
|
|
6
7
|
export class Service extends DatabaseService<Model> {
|
|
7
8
|
public constructor() {
|
|
@@ -25,7 +26,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
25
26
|
);
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
if (!projectCallSmsConfig.
|
|
29
|
+
if (!projectCallSmsConfig.twilioPrimaryPhoneNumber) {
|
|
29
30
|
throw new BadDataException(
|
|
30
31
|
"Project Call and SMS Config twilio phone number is not set",
|
|
31
32
|
);
|
|
@@ -40,7 +41,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
40
41
|
return {
|
|
41
42
|
accountSid: projectCallSmsConfig.twilioAccountSID.toString(),
|
|
42
43
|
authToken: projectCallSmsConfig.twilioAuthToken.toString(),
|
|
43
|
-
|
|
44
|
+
primaryPhoneNumber: projectCallSmsConfig.twilioPrimaryPhoneNumber,
|
|
45
|
+
secondaryPhoneNumbers:
|
|
46
|
+
projectCallSmsConfig.twilioSecondaryPhoneNumbers &&
|
|
47
|
+
projectCallSmsConfig.twilioSecondaryPhoneNumbers.length > 0
|
|
48
|
+
? projectCallSmsConfig.twilioSecondaryPhoneNumbers
|
|
49
|
+
.split(",")
|
|
50
|
+
.map((phone: string) => {
|
|
51
|
+
return new Phone(phone);
|
|
52
|
+
})
|
|
53
|
+
: [],
|
|
44
54
|
};
|
|
45
55
|
}
|
|
46
56
|
}
|
|
@@ -36,7 +36,10 @@ export class SmsService extends BaseService {
|
|
|
36
36
|
? {
|
|
37
37
|
accountSid: options.customTwilioConfig.accountSid!,
|
|
38
38
|
authToken: options.customTwilioConfig.authToken!,
|
|
39
|
-
|
|
39
|
+
primaryPhoneNumber:
|
|
40
|
+
options.customTwilioConfig.primaryPhoneNumber.toString(),
|
|
41
|
+
secondaryPhoneNumbers:
|
|
42
|
+
options.customTwilioConfig.secondaryPhoneNumbers?.toString(),
|
|
40
43
|
}
|
|
41
44
|
: undefined,
|
|
42
45
|
};
|
|
@@ -262,7 +262,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
262
262
|
_id: true,
|
|
263
263
|
twilioAccountSID: true,
|
|
264
264
|
twilioAuthToken: true,
|
|
265
|
-
|
|
265
|
+
twilioPrimaryPhoneNumber: true,
|
|
266
|
+
twilioSecondaryPhoneNumbers: true,
|
|
266
267
|
},
|
|
267
268
|
},
|
|
268
269
|
props: {
|
|
@@ -795,7 +796,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
795
796
|
_id: true,
|
|
796
797
|
twilioAccountSID: true,
|
|
797
798
|
twilioAuthToken: true,
|
|
798
|
-
|
|
799
|
+
twilioPrimaryPhoneNumber: true,
|
|
800
|
+
twilioSecondaryPhoneNumbers: true,
|
|
799
801
|
},
|
|
800
802
|
subscriberTimezones: true,
|
|
801
803
|
reportDataInDays: true,
|
|
@@ -839,6 +839,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
839
839
|
userBelongsToTeamId?: ObjectID | undefined;
|
|
840
840
|
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
|
|
841
841
|
onCallScheduleId?: ObjectID | undefined;
|
|
842
|
+
overridedByUserId?: ObjectID | undefined;
|
|
842
843
|
},
|
|
843
844
|
): Promise<void> {
|
|
844
845
|
// add user notification log.
|
|
@@ -887,6 +888,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
887
888
|
userOnCallLog.status = UserNotificationExecutionStatus.Scheduled;
|
|
888
889
|
userOnCallLog.statusMessage = "Scheduled";
|
|
889
890
|
|
|
891
|
+
if (options.overridedByUserId) {
|
|
892
|
+
userOnCallLog.overridedByUserId = options.overridedByUserId;
|
|
893
|
+
}
|
|
894
|
+
|
|
890
895
|
await UserOnCallLogService.create({
|
|
891
896
|
data: userOnCallLog,
|
|
892
897
|
props: {
|
package/Types/Permission.ts
CHANGED
|
@@ -512,6 +512,11 @@ enum Permission {
|
|
|
512
512
|
DeleteProjectOnCallDutyPolicyEscalationRule = "DeleteProjectOnCallDutyPolicyEscalationRule",
|
|
513
513
|
ReadProjectOnCallDutyPolicyEscalationRule = "ReadProjectOnCallDutyPolicyEscalationRule",
|
|
514
514
|
|
|
515
|
+
CreateOnCallDutyPolicyUserOverride = "CreateOnCallDutyPolicyUserOverride",
|
|
516
|
+
EditOnCallDutyPolicyUserOverride = "EditOnCallDutyPolicyUserOverride",
|
|
517
|
+
DeleteOnCallDutyPolicyUserOverride = "DeleteOnCallDutyPolicyUserOverride",
|
|
518
|
+
ReadOnCallDutyPolicyUserOverride = "ReadOnCallDutyPolicyUserOverride",
|
|
519
|
+
|
|
515
520
|
// Resource Permissions (Team Permission)
|
|
516
521
|
CreateProjectOnCallDutyPolicyEscalationRuleUser = "CreateProjectOnCallDutyPolicyEscalationRuleUser",
|
|
517
522
|
EditProjectOnCallDutyPolicyEscalationRuleUser = "EditProjectOnCallDutyPolicyEscalationRuleUser",
|
|
@@ -2378,6 +2383,39 @@ export class PermissionHelper {
|
|
|
2378
2383
|
isAccessControlPermission: false,
|
|
2379
2384
|
},
|
|
2380
2385
|
|
|
2386
|
+
{
|
|
2387
|
+
permission: Permission.CreateOnCallDutyPolicyUserOverride,
|
|
2388
|
+
title: "Create On-Call Duty Policy User Override",
|
|
2389
|
+
description:
|
|
2390
|
+
"This permission can create on-call duty policy user override this project.",
|
|
2391
|
+
isAssignableToTenant: true,
|
|
2392
|
+
isAccessControlPermission: false,
|
|
2393
|
+
},
|
|
2394
|
+
{
|
|
2395
|
+
permission: Permission.DeleteOnCallDutyPolicyUserOverride,
|
|
2396
|
+
title: "Delete On-Call Duty Policy User Override",
|
|
2397
|
+
description:
|
|
2398
|
+
"This permission can delete on-call duty policy user override of this project.",
|
|
2399
|
+
isAssignableToTenant: true,
|
|
2400
|
+
isAccessControlPermission: false,
|
|
2401
|
+
},
|
|
2402
|
+
{
|
|
2403
|
+
permission: Permission.EditOnCallDutyPolicyUserOverride,
|
|
2404
|
+
title: "Edit On-Call Duty Policy User Override",
|
|
2405
|
+
description:
|
|
2406
|
+
"This permission can edit on-call duty policy user override of this project.",
|
|
2407
|
+
isAssignableToTenant: true,
|
|
2408
|
+
isAccessControlPermission: false,
|
|
2409
|
+
},
|
|
2410
|
+
{
|
|
2411
|
+
permission: Permission.ReadOnCallDutyPolicyUserOverride,
|
|
2412
|
+
title: "Read On-Call Duty Policy User Override",
|
|
2413
|
+
description:
|
|
2414
|
+
"This permission can read on-call duty policy user override of this project.",
|
|
2415
|
+
isAssignableToTenant: true,
|
|
2416
|
+
isAccessControlPermission: false,
|
|
2417
|
+
},
|
|
2418
|
+
|
|
2381
2419
|
{
|
|
2382
2420
|
permission: Permission.CreateProjectOnCallDutyPolicy,
|
|
2383
2421
|
title: "Create On-Call Duty Policy",
|