@oneuptime/common 7.0.4006 → 7.0.4019
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/OnCallDutyPolicySchedule.ts +68 -1
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +0 -79
- package/Server/API/OnCallDutyPolicyAPI.ts +87 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1743692467814-MigrationName.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1743714801105-MigrationName.ts +23 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +243 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +46 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +237 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +210 -0
- package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +61 -1
- package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +63 -0
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +597 -18
- package/Server/Services/OnCallDutyPolicyService.ts +129 -0
- package/Server/Services/TeamService.ts +36 -0
- package/Server/Services/UserNotificationSettingService.ts +114 -237
- package/Server/Services/UserService.ts +21 -0
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +2 -2
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +3 -3
- package/Types/Date.ts +23 -7
- package/Types/Email/EmailTemplateType.ts +6 -0
- package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
- package/Types/OnCallDutyPolicy/Layer.ts +104 -20
- package/UI/Components/Alerts/Alert.tsx +6 -5
- package/UI/Components/HeaderAlert/HeaderAlert.tsx +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +70 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +0 -82
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
- package/build/dist/Server/API/OnCallDutyPolicyAPI.js +44 -0
- package/build/dist/Server/API/OnCallDutyPolicyAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1743692467814-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1743692467814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1743714801105-MigrationName.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1743714801105-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +170 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +40 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +170 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +152 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +39 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +42 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +387 -8
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyService.js +101 -0
- package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +27 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +35 -202
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +17 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +2 -2
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +3 -3
- package/build/dist/Types/Date.js +19 -7
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +5 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +6 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +66 -11
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/UI/Components/Alerts/Alert.js +4 -4
- package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +2 -2
- package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
- package/package.json +2 -2
|
@@ -9,6 +9,18 @@ import OnCallDutyPolicyExecutionLog from "Common/Models/DatabaseModels/OnCallDut
|
|
|
9
9
|
import DatabaseConfig from "../DatabaseConfig";
|
|
10
10
|
import URL from "../../Types/API/URL";
|
|
11
11
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
12
|
+
import OnCallDutyPolicySchedule from "../../Models/DatabaseModels/OnCallDutyPolicySchedule";
|
|
13
|
+
import OnCallDutyPolicyScheduleService from "./OnCallDutyPolicyScheduleService";
|
|
14
|
+
import TeamService from "./TeamService";
|
|
15
|
+
import Team from "../../Models/DatabaseModels/Team";
|
|
16
|
+
import OnCallDutyPolicyEscalationRuleUser from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser";
|
|
17
|
+
import OnCallDutyPolicyEscalationRuleUserService from "./OnCallDutyPolicyEscalationRuleUserService";
|
|
18
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
19
|
+
import OnCallDutyPolicyEscalationRuleTeam from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam";
|
|
20
|
+
import OnCallDutyPolicyEscalationRuleTeamService from "./OnCallDutyPolicyEscalationRuleTeamService";
|
|
21
|
+
import QueryHelper from "../Types/Database/QueryHelper";
|
|
22
|
+
import OnCallDutyPolicyEscalationRuleSchedule from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule";
|
|
23
|
+
import OnCallDutyPolicyEscalationRuleScheduleService from "./OnCallDutyPolicyEscalationRuleScheduleService";
|
|
12
24
|
|
|
13
25
|
export class Service extends DatabaseService<OnCallDutyPolicy> {
|
|
14
26
|
public constructor() {
|
|
@@ -100,5 +112,122 @@ export class Service extends DatabaseService<OnCallDutyPolicy> {
|
|
|
100
112
|
},
|
|
101
113
|
});
|
|
102
114
|
}
|
|
115
|
+
|
|
116
|
+
public async getOnCallPoliciesWhereUserIsOnCallDuty(data: {
|
|
117
|
+
projectId: ObjectID;
|
|
118
|
+
userId: ObjectID;
|
|
119
|
+
}): Promise<{
|
|
120
|
+
escalationRulesByUser: Array<OnCallDutyPolicyEscalationRuleUser>;
|
|
121
|
+
escalationRulesByTeam: Array<OnCallDutyPolicyEscalationRuleTeam>;
|
|
122
|
+
escalationRulesBySchedule: Array<OnCallDutyPolicyEscalationRuleSchedule>;
|
|
123
|
+
}> {
|
|
124
|
+
// get all schedules where user is on call duty.
|
|
125
|
+
const onCallSchedules: Array<OnCallDutyPolicySchedule> =
|
|
126
|
+
await OnCallDutyPolicyScheduleService.getOnCallSchedulesWhereUserIsOnCallDuty(
|
|
127
|
+
data,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const teams: Array<Team> = await TeamService.getTeamsUserIsAPartOf({
|
|
131
|
+
userId: data.userId,
|
|
132
|
+
projectId: data.projectId,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// get escalationPolicies by user, team and schedule.
|
|
136
|
+
const escalationRulesByUser: Array<OnCallDutyPolicyEscalationRuleUser> =
|
|
137
|
+
await OnCallDutyPolicyEscalationRuleUserService.findBy({
|
|
138
|
+
query: {
|
|
139
|
+
userId: data.userId!,
|
|
140
|
+
projectId: data.projectId!,
|
|
141
|
+
},
|
|
142
|
+
select: {
|
|
143
|
+
onCallDutyPolicyEscalationRule: {
|
|
144
|
+
name: true,
|
|
145
|
+
_id: true,
|
|
146
|
+
order: true,
|
|
147
|
+
},
|
|
148
|
+
onCallDutyPolicy: {
|
|
149
|
+
name: true,
|
|
150
|
+
_id: true,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
limit: LIMIT_PER_PROJECT,
|
|
154
|
+
skip: 0,
|
|
155
|
+
props: {
|
|
156
|
+
isRoot: true,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// do the same for teams.
|
|
161
|
+
const escalationRulesByTeam: Array<OnCallDutyPolicyEscalationRuleTeam> =
|
|
162
|
+
await OnCallDutyPolicyEscalationRuleTeamService.findBy({
|
|
163
|
+
query: {
|
|
164
|
+
teamId: QueryHelper.any(
|
|
165
|
+
teams.map((team: Team) => {
|
|
166
|
+
return team.id!;
|
|
167
|
+
}),
|
|
168
|
+
),
|
|
169
|
+
projectId: data.projectId!,
|
|
170
|
+
},
|
|
171
|
+
select: {
|
|
172
|
+
onCallDutyPolicy: {
|
|
173
|
+
name: true,
|
|
174
|
+
_id: true,
|
|
175
|
+
},
|
|
176
|
+
onCallDutyPolicyEscalationRule: {
|
|
177
|
+
name: true,
|
|
178
|
+
_id: true,
|
|
179
|
+
order: true,
|
|
180
|
+
},
|
|
181
|
+
team: {
|
|
182
|
+
name: true,
|
|
183
|
+
_id: true,
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
limit: LIMIT_PER_PROJECT,
|
|
187
|
+
skip: 0,
|
|
188
|
+
props: {
|
|
189
|
+
isRoot: true,
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// do the same for schedules.
|
|
194
|
+
const escalationRulesBySchedule: Array<OnCallDutyPolicyEscalationRuleSchedule> =
|
|
195
|
+
await OnCallDutyPolicyEscalationRuleScheduleService.findBy({
|
|
196
|
+
query: {
|
|
197
|
+
onCallDutyPolicyScheduleId: QueryHelper.any(
|
|
198
|
+
onCallSchedules.map((schedule: OnCallDutyPolicySchedule) => {
|
|
199
|
+
return schedule.id!;
|
|
200
|
+
}),
|
|
201
|
+
),
|
|
202
|
+
projectId: data.projectId!,
|
|
203
|
+
},
|
|
204
|
+
select: {
|
|
205
|
+
onCallDutyPolicy: {
|
|
206
|
+
name: true,
|
|
207
|
+
_id: true,
|
|
208
|
+
},
|
|
209
|
+
onCallDutyPolicyEscalationRule: {
|
|
210
|
+
name: true,
|
|
211
|
+
_id: true,
|
|
212
|
+
order: true,
|
|
213
|
+
},
|
|
214
|
+
onCallDutyPolicySchedule: {
|
|
215
|
+
name: true,
|
|
216
|
+
_id: true,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
limit: LIMIT_PER_PROJECT,
|
|
220
|
+
skip: 0,
|
|
221
|
+
props: {
|
|
222
|
+
isRoot: true,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
escalationRulesByUser: escalationRulesByUser,
|
|
228
|
+
escalationRulesByTeam: escalationRulesByTeam,
|
|
229
|
+
escalationRulesBySchedule: escalationRulesBySchedule,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
103
232
|
}
|
|
104
233
|
export default new Service();
|
|
@@ -6,12 +6,48 @@ import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
|
6
6
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
7
7
|
import Model from "Common/Models/DatabaseModels/Team";
|
|
8
8
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
9
|
+
import ObjectID from "../../Types/ObjectID";
|
|
10
|
+
import TeamMember from "../../Models/DatabaseModels/TeamMember";
|
|
11
|
+
import TeamMemberService from "./TeamMemberService";
|
|
9
12
|
|
|
10
13
|
export class Service extends DatabaseService<Model> {
|
|
11
14
|
public constructor() {
|
|
12
15
|
super(Model);
|
|
13
16
|
}
|
|
14
17
|
|
|
18
|
+
public async getTeamsUserIsAPartOf(data: {
|
|
19
|
+
userId: ObjectID;
|
|
20
|
+
projectId: ObjectID;
|
|
21
|
+
}): Promise<Array<Model>> {
|
|
22
|
+
const teamMembers: Array<TeamMember> = await TeamMemberService.findBy({
|
|
23
|
+
query: {
|
|
24
|
+
userId: data.userId,
|
|
25
|
+
projectId: data.projectId,
|
|
26
|
+
},
|
|
27
|
+
select: {
|
|
28
|
+
team: {
|
|
29
|
+
name: true,
|
|
30
|
+
_id: true,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
limit: LIMIT_MAX,
|
|
34
|
+
skip: 0,
|
|
35
|
+
props: {
|
|
36
|
+
isRoot: true,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const teams: Array<Model> = [];
|
|
41
|
+
|
|
42
|
+
for (const teamMember of teamMembers) {
|
|
43
|
+
if (teamMember.team) {
|
|
44
|
+
teams.push(teamMember.team);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return teams;
|
|
49
|
+
}
|
|
50
|
+
|
|
15
51
|
@CaptureSpan()
|
|
16
52
|
protected override async onBeforeUpdate(
|
|
17
53
|
updateBy: UpdateBy<Model>,
|
|
@@ -197,266 +197,143 @@ export class Service extends DatabaseService<UserNotificationSetting> {
|
|
|
197
197
|
userId: ObjectID,
|
|
198
198
|
projectId: ObjectID,
|
|
199
199
|
): Promise<void> {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
200
|
+
await this.addProbeOwnerNotificationSettings(userId, projectId);
|
|
201
|
+
await this.addIncidentNotificationSettings(userId, projectId);
|
|
202
|
+
await this.addMonitorNotificationSettings(userId, projectId);
|
|
203
|
+
await this.addOnCallNotificationSettings(userId, projectId);
|
|
204
|
+
await this.addAlertNotificationSettings(userId, projectId);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private async addProbeOwnerNotificationSettings(
|
|
208
|
+
userId: ObjectID,
|
|
209
|
+
projectId: ObjectID,
|
|
210
|
+
): Promise<void> {
|
|
211
|
+
await this.addNotificationSettingIfNotExists(
|
|
212
|
+
userId,
|
|
213
|
+
projectId,
|
|
214
|
+
NotificationSettingEventType.SEND_PROBE_OWNER_ADDED_NOTIFICATION,
|
|
212
215
|
);
|
|
213
216
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
item.alertByEmail = true;
|
|
217
|
+
await this.addNotificationSettingIfNotExists(
|
|
218
|
+
userId,
|
|
219
|
+
projectId,
|
|
220
|
+
NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
|
|
221
|
+
);
|
|
222
|
+
}
|
|
221
223
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
224
|
+
private async addIncidentNotificationSettings(
|
|
225
|
+
userId: ObjectID,
|
|
226
|
+
projectId: ObjectID,
|
|
227
|
+
): Promise<void> {
|
|
228
|
+
await this.addNotificationSettingIfNotExists(
|
|
229
|
+
userId,
|
|
230
|
+
projectId,
|
|
231
|
+
NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION,
|
|
232
|
+
);
|
|
229
233
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
|
|
237
|
-
},
|
|
238
|
-
props: {
|
|
239
|
-
isRoot: true,
|
|
240
|
-
},
|
|
241
|
-
});
|
|
234
|
+
await this.addNotificationSettingIfNotExists(
|
|
235
|
+
userId,
|
|
236
|
+
projectId,
|
|
237
|
+
NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
242
240
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
241
|
+
private async addMonitorNotificationSettings(
|
|
242
|
+
userId: ObjectID,
|
|
243
|
+
projectId: ObjectID,
|
|
244
|
+
): Promise<void> {
|
|
245
|
+
await this.addNotificationSettingIfNotExists(
|
|
246
|
+
userId,
|
|
247
|
+
projectId,
|
|
248
|
+
NotificationSettingEventType.SEND_MONITOR_STATUS_CHANGED_OWNER_NOTIFICATION,
|
|
249
|
+
);
|
|
250
250
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
});
|
|
257
|
-
}
|
|
251
|
+
await this.addNotificationSettingIfNotExists(
|
|
252
|
+
userId,
|
|
253
|
+
projectId,
|
|
254
|
+
NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR,
|
|
255
|
+
);
|
|
258
256
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
projectId,
|
|
264
|
-
eventType:
|
|
265
|
-
NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION,
|
|
266
|
-
},
|
|
267
|
-
props: {
|
|
268
|
-
isRoot: true,
|
|
269
|
-
},
|
|
270
|
-
},
|
|
257
|
+
await this.addNotificationSettingIfNotExists(
|
|
258
|
+
userId,
|
|
259
|
+
projectId,
|
|
260
|
+
NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES,
|
|
271
261
|
);
|
|
262
|
+
}
|
|
272
263
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
264
|
+
public async addOnCallNotificationSettings(
|
|
265
|
+
userId: ObjectID,
|
|
266
|
+
projectId: ObjectID,
|
|
267
|
+
): Promise<void> {
|
|
268
|
+
await this.addNotificationSettingIfNotExists(
|
|
269
|
+
userId,
|
|
270
|
+
projectId,
|
|
271
|
+
NotificationSettingEventType.SEND_WHEN_USER_IS_ON_CALL_ROSTER,
|
|
272
|
+
);
|
|
280
273
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
274
|
+
await this.addNotificationSettingIfNotExists(
|
|
275
|
+
userId,
|
|
276
|
+
projectId,
|
|
277
|
+
NotificationSettingEventType.SEND_WHEN_USER_IS_NEXT_ON_CALL_ROSTER,
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
await this.addNotificationSettingIfNotExists(
|
|
281
|
+
userId,
|
|
282
|
+
projectId,
|
|
283
|
+
NotificationSettingEventType.SEND_WHEN_USER_IS_ADDED_TO_ON_CALL_POLICY,
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
await this.addNotificationSettingIfNotExists(
|
|
287
|
+
userId,
|
|
288
|
+
projectId,
|
|
289
|
+
NotificationSettingEventType.SEND_WHEN_USER_IS_REMOVED_FROM_ON_CALL_POLICY,
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
await this.addNotificationSettingIfNotExists(
|
|
293
|
+
userId,
|
|
294
|
+
projectId,
|
|
295
|
+
NotificationSettingEventType.SEND_WHEN_USER_IS_NO_LONGER_ACTIVE_ON_ON_CALL_ROSTER,
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
private async addAlertNotificationSettings(
|
|
300
|
+
userId: ObjectID,
|
|
301
|
+
projectId: ObjectID,
|
|
302
|
+
): Promise<void> {
|
|
303
|
+
await this.addNotificationSettingIfNotExists(
|
|
304
|
+
userId,
|
|
305
|
+
projectId,
|
|
306
|
+
NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION,
|
|
307
|
+
);
|
|
288
308
|
|
|
289
|
-
|
|
309
|
+
await this.addNotificationSettingIfNotExists(
|
|
310
|
+
userId,
|
|
311
|
+
projectId,
|
|
312
|
+
NotificationSettingEventType.SEND_ALERT_STATE_CHANGED_OWNER_NOTIFICATION,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private async addNotificationSettingIfNotExists(
|
|
317
|
+
userId: ObjectID,
|
|
318
|
+
projectId: ObjectID,
|
|
319
|
+
eventType: NotificationSettingEventType,
|
|
320
|
+
): Promise<void> {
|
|
321
|
+
const existingNotification: PositiveNumber = await this.countBy({
|
|
290
322
|
query: {
|
|
291
323
|
userId,
|
|
292
324
|
projectId,
|
|
293
|
-
eventType
|
|
294
|
-
NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION,
|
|
325
|
+
eventType,
|
|
295
326
|
},
|
|
296
327
|
props: {
|
|
297
328
|
isRoot: true,
|
|
298
329
|
},
|
|
299
330
|
});
|
|
300
331
|
|
|
301
|
-
if (
|
|
302
|
-
const item: UserNotificationSetting = new UserNotificationSetting();
|
|
303
|
-
item.userId = userId;
|
|
304
|
-
item.projectId = projectId;
|
|
305
|
-
item.eventType =
|
|
306
|
-
NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION;
|
|
307
|
-
item.alertByEmail = true;
|
|
308
|
-
|
|
309
|
-
await this.create({
|
|
310
|
-
data: item,
|
|
311
|
-
props: {
|
|
312
|
-
isRoot: true,
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// check monitor state changed notification
|
|
318
|
-
const monitorStateChangedNotificationEvent: PositiveNumber =
|
|
319
|
-
await this.countBy({
|
|
320
|
-
query: {
|
|
321
|
-
userId,
|
|
322
|
-
projectId,
|
|
323
|
-
eventType:
|
|
324
|
-
NotificationSettingEventType.SEND_MONITOR_STATUS_CHANGED_OWNER_NOTIFICATION,
|
|
325
|
-
},
|
|
326
|
-
props: {
|
|
327
|
-
isRoot: true,
|
|
328
|
-
},
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
if (monitorStateChangedNotificationEvent.toNumber() === 0) {
|
|
332
|
-
const item: UserNotificationSetting = new UserNotificationSetting();
|
|
333
|
-
item.userId = userId;
|
|
334
|
-
item.projectId = projectId;
|
|
335
|
-
item.eventType =
|
|
336
|
-
NotificationSettingEventType.SEND_MONITOR_STATUS_CHANGED_OWNER_NOTIFICATION;
|
|
337
|
-
item.alertByEmail = true;
|
|
338
|
-
|
|
339
|
-
await this.create({
|
|
340
|
-
data: item,
|
|
341
|
-
props: {
|
|
342
|
-
isRoot: true,
|
|
343
|
-
},
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR
|
|
348
|
-
|
|
349
|
-
const monitorNoProbesNotificationEvent: PositiveNumber = await this.countBy(
|
|
350
|
-
{
|
|
351
|
-
query: {
|
|
352
|
-
userId,
|
|
353
|
-
projectId,
|
|
354
|
-
eventType:
|
|
355
|
-
NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR,
|
|
356
|
-
},
|
|
357
|
-
props: {
|
|
358
|
-
isRoot: true,
|
|
359
|
-
},
|
|
360
|
-
},
|
|
361
|
-
);
|
|
362
|
-
|
|
363
|
-
if (monitorNoProbesNotificationEvent.toNumber() === 0) {
|
|
364
|
-
const item: UserNotificationSetting = new UserNotificationSetting();
|
|
365
|
-
item.userId = userId;
|
|
366
|
-
item.projectId = projectId;
|
|
367
|
-
item.eventType =
|
|
368
|
-
NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR;
|
|
369
|
-
item.alertByEmail = true;
|
|
370
|
-
|
|
371
|
-
await this.create({
|
|
372
|
-
data: item,
|
|
373
|
-
props: {
|
|
374
|
-
isRoot: true,
|
|
375
|
-
},
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES
|
|
380
|
-
|
|
381
|
-
const monitorProbeStatusChangedNotificationEvent: PositiveNumber =
|
|
382
|
-
await this.countBy({
|
|
383
|
-
query: {
|
|
384
|
-
userId,
|
|
385
|
-
projectId,
|
|
386
|
-
eventType:
|
|
387
|
-
NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES,
|
|
388
|
-
},
|
|
389
|
-
props: {
|
|
390
|
-
isRoot: true,
|
|
391
|
-
},
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
if (monitorProbeStatusChangedNotificationEvent.toNumber() === 0) {
|
|
395
|
-
const item: UserNotificationSetting = new UserNotificationSetting();
|
|
396
|
-
item.userId = userId;
|
|
397
|
-
item.projectId = projectId;
|
|
398
|
-
item.eventType =
|
|
399
|
-
NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES;
|
|
400
|
-
item.alertByEmail = true;
|
|
401
|
-
|
|
402
|
-
await this.create({
|
|
403
|
-
data: item,
|
|
404
|
-
props: {
|
|
405
|
-
isRoot: true,
|
|
406
|
-
},
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// check incident state changed notification
|
|
411
|
-
const incidentStateChangedNotificationEvent: PositiveNumber =
|
|
412
|
-
await this.countBy({
|
|
413
|
-
query: {
|
|
414
|
-
userId,
|
|
415
|
-
projectId,
|
|
416
|
-
eventType:
|
|
417
|
-
NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION,
|
|
418
|
-
},
|
|
419
|
-
props: {
|
|
420
|
-
isRoot: true,
|
|
421
|
-
},
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
if (incidentStateChangedNotificationEvent.toNumber() === 0) {
|
|
425
|
-
const item: UserNotificationSetting = new UserNotificationSetting();
|
|
426
|
-
item.userId = userId;
|
|
427
|
-
item.projectId = projectId;
|
|
428
|
-
item.eventType =
|
|
429
|
-
NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION;
|
|
430
|
-
item.alertByEmail = true;
|
|
431
|
-
|
|
432
|
-
await this.create({
|
|
433
|
-
data: item,
|
|
434
|
-
props: {
|
|
435
|
-
isRoot: true,
|
|
436
|
-
},
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// check alert state changed notification
|
|
441
|
-
const alertStateChangedNotificationEvent: PositiveNumber =
|
|
442
|
-
await this.countBy({
|
|
443
|
-
query: {
|
|
444
|
-
userId,
|
|
445
|
-
projectId,
|
|
446
|
-
eventType:
|
|
447
|
-
NotificationSettingEventType.SEND_ALERT_STATE_CHANGED_OWNER_NOTIFICATION,
|
|
448
|
-
},
|
|
449
|
-
props: {
|
|
450
|
-
isRoot: true,
|
|
451
|
-
},
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
if (alertStateChangedNotificationEvent.toNumber() === 0) {
|
|
332
|
+
if (existingNotification.toNumber() === 0) {
|
|
455
333
|
const item: UserNotificationSetting = new UserNotificationSetting();
|
|
456
334
|
item.userId = userId;
|
|
457
335
|
item.projectId = projectId;
|
|
458
|
-
item.eventType =
|
|
459
|
-
NotificationSettingEventType.SEND_ALERT_STATE_CHANGED_OWNER_NOTIFICATION;
|
|
336
|
+
item.eventType = eventType;
|
|
460
337
|
item.alertByEmail = true;
|
|
461
338
|
|
|
462
339
|
await this.create({
|
|
@@ -34,6 +34,7 @@ import UserTwoFactorAuthService from "./UserTwoFactorAuthService";
|
|
|
34
34
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
35
35
|
import Name from "../../Types/Name";
|
|
36
36
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
37
|
+
import Timezone from "../../Types/Timezone";
|
|
37
38
|
|
|
38
39
|
export class Service extends DatabaseService<Model> {
|
|
39
40
|
public constructor() {
|
|
@@ -364,6 +365,26 @@ export class Service extends DatabaseService<Model> {
|
|
|
364
365
|
props: props,
|
|
365
366
|
});
|
|
366
367
|
}
|
|
368
|
+
|
|
369
|
+
public async getTimezoneForUser(userId: ObjectID): Promise<Timezone | null> {
|
|
370
|
+
const user: Model | null = await this.findOneBy({
|
|
371
|
+
query: {
|
|
372
|
+
_id: userId,
|
|
373
|
+
},
|
|
374
|
+
select: {
|
|
375
|
+
timezone: true,
|
|
376
|
+
},
|
|
377
|
+
props: {
|
|
378
|
+
isRoot: true,
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
if (!user) {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return user.timezone || null;
|
|
387
|
+
}
|
|
367
388
|
}
|
|
368
389
|
|
|
369
390
|
export default new Service();
|
|
@@ -503,7 +503,7 @@ export default class SlackAlertActions {
|
|
|
503
503
|
// send a message to the channel visible to user, that the alert has already been Resolved.
|
|
504
504
|
const markdwonPayload: WorkspacePayloadMarkdown = {
|
|
505
505
|
_type: "WorkspacePayloadMarkdown",
|
|
506
|
-
text: `@${slackUsername}, unfortunately you cannot execute the on
|
|
506
|
+
text: `@${slackUsername}, unfortunately you cannot execute the on-call policy for **[Alert ${alertNumber?.toString()}](${await AlertService.getAlertLinkInDashboard(slackRequest.projectId!, alertId)})**. It has already been resolved.`,
|
|
507
507
|
};
|
|
508
508
|
|
|
509
509
|
await SlackUtil.sendDirectMessageToUser({
|
|
@@ -529,7 +529,7 @@ export default class SlackAlertActions {
|
|
|
529
529
|
const onCallPolicyString: string =
|
|
530
530
|
data.slackRequest.viewValues["onCallPolicy"].toString();
|
|
531
531
|
|
|
532
|
-
// get the on
|
|
532
|
+
// get the on-call policy id.
|
|
533
533
|
const onCallPolicyId: ObjectID = new ObjectID(onCallPolicyString);
|
|
534
534
|
|
|
535
535
|
await OnCallDutyPolicyService.executePolicy(onCallPolicyId, {
|
|
@@ -400,7 +400,7 @@ export default class SlackIncidentActions {
|
|
|
400
400
|
blocks.push(monitorStatusDropdown);
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
// add on
|
|
403
|
+
// add on-call policy dropdown.
|
|
404
404
|
|
|
405
405
|
const onCallPolicies: Array<OnCallDutyPolicy> =
|
|
406
406
|
await OnCallDutyPolicyService.findBy({
|
|
@@ -957,7 +957,7 @@ export default class SlackIncidentActions {
|
|
|
957
957
|
// send a message to the channel visible to user, that the incident has already been Resolved.
|
|
958
958
|
const markdwonPayload: WorkspacePayloadMarkdown = {
|
|
959
959
|
_type: "WorkspacePayloadMarkdown",
|
|
960
|
-
text: `@${slackUsername}, unfortunately you cannot execute the on
|
|
960
|
+
text: `@${slackUsername}, unfortunately you cannot execute the on-call policy for **[Incident ${incidentNumber?.toString()}](${await IncidentService.getIncidentLinkInDashboard(slackRequest.projectId!, incidentId)})**. It has already been resolved.`,
|
|
961
961
|
};
|
|
962
962
|
|
|
963
963
|
await SlackUtil.sendDirectMessageToUser({
|
|
@@ -983,7 +983,7 @@ export default class SlackIncidentActions {
|
|
|
983
983
|
const onCallPolicyString: string =
|
|
984
984
|
data.slackRequest.viewValues["onCallPolicy"].toString();
|
|
985
985
|
|
|
986
|
-
// get the on
|
|
986
|
+
// get the on-call policy id.
|
|
987
987
|
const onCallPolicyId: ObjectID = new ObjectID(onCallPolicyString);
|
|
988
988
|
|
|
989
989
|
await OnCallDutyPolicyService.executePolicy(onCallPolicyId, {
|