@oneuptime/common 7.0.3786 → 7.0.3815
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/Server/API/SlackAPI.ts +68 -0
- package/Server/Services/AccessTokenService.ts +21 -0
- package/Server/Services/AlertFeedService.ts +98 -0
- package/Server/Services/AlertInternalNoteService.ts +49 -8
- package/Server/Services/AlertOwnerTeamService.ts +50 -2
- package/Server/Services/AlertOwnerUserService.ts +52 -2
- package/Server/Services/AlertService.ts +236 -37
- package/Server/Services/AlertStateService.ts +24 -0
- package/Server/Services/AlertStateTimelineService.ts +30 -2
- package/Server/Services/IncidentInternalNoteService.ts +6 -6
- package/Server/Services/IncidentPublicNoteService.ts +7 -4
- package/Server/Services/IncidentStateTimelineService.ts +2 -1
- package/Server/Services/ScheduledMaintenanceFeedService.ts +103 -0
- package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +50 -6
- package/Server/Services/ScheduledMaintenanceOwnerTeamService.ts +37 -0
- package/Server/Services/ScheduledMaintenanceOwnerUserService.ts +34 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +49 -7
- package/Server/Services/ScheduledMaintenanceService.ts +375 -12
- package/Server/Services/ScheduledMaintenanceStateService.ts +122 -34
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +33 -1
- package/Server/Services/WorkspaceNotificationRuleService.ts +12 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.ts +38 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.ts +116 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.ts +36 -115
- package/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.ts +108 -0
- package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +20 -2
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +697 -0
- package/Server/Utils/Workspace/Slack/Actions/Auth.ts +9 -2
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +9 -3
- package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +956 -0
- package/Server/Utils/Workspace/Slack/Messages/Alert.ts +116 -0
- package/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.ts +108 -0
- package/Server/Utils/Workspace/Slack/Slack.ts +48 -2
- package/Server/Utils/Workspace/Slack/app-manifest.json +3 -3
- package/Server/Utils/Workspace/WorkspaceBase.ts +14 -0
- package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +69 -0
- package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +73 -0
- package/Types/Date.ts +5 -0
- package/Types/Workspace/WorkspaceMessagePayload.ts +9 -0
- package/build/dist/Server/API/SlackAPI.js +54 -0
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +11 -0
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertFeedService.js +60 -0
- package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
- package/build/dist/Server/Services/AlertInternalNoteService.js +39 -8
- package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerTeamService.js +40 -2
- package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerUserService.js +41 -3
- package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +192 -35
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertStateService.js +13 -0
- package/build/dist/Server/Services/AlertStateService.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +26 -2
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentInternalNoteService.js +6 -6
- package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +5 -4
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js +60 -0
- package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +36 -6
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js +24 -0
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js +22 -0
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +36 -7
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +275 -13
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateService.js +52 -4
- package/build/dist/Server/Services/ScheduledMaintenanceStateService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +28 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +10 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js +37 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.js +82 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js +33 -99
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.js +74 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +20 -2
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +425 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +2 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +5 -2
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +599 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/Alert.js +82 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/Alert.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.js +74 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +34 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +3 -3
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +8 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js +48 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js +47 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -0
- package/build/dist/Types/Date.js +4 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/package.json +2 -2
|
@@ -52,6 +52,10 @@ import { ScheduledMaintenanceFeedEventType } from "../../Models/DatabaseModels/S
|
|
|
52
52
|
import { Gray500, Red500 } from "../../Types/BrandColors";
|
|
53
53
|
import Label from "../../Models/DatabaseModels/Label";
|
|
54
54
|
import LabelService from "./LabelService";
|
|
55
|
+
import WorkspaceType from "../../Types/Workspace/WorkspaceType";
|
|
56
|
+
import NotificationRuleWorkspaceChannel from "../../Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel";
|
|
57
|
+
import { MessageBlocksByWorkspaceType } from "./WorkspaceNotificationRuleService";
|
|
58
|
+
import ScheduledMaintenanceWorkspaceMessages from "../Utils/Workspace/WorkspaceMessages/ScheduledMaintenance";
|
|
55
59
|
|
|
56
60
|
export class Service extends DatabaseService<Model> {
|
|
57
61
|
public constructor() {
|
|
@@ -163,7 +167,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
if (!statuspage.showScheduledMaintenanceEventsOnStatusPage) {
|
|
166
|
-
continue; // Do not send notification to subscribers if
|
|
170
|
+
continue; // Do not send notification to subscribers if scheduledMaintenances are not visible on status page.
|
|
167
171
|
}
|
|
168
172
|
|
|
169
173
|
const subscribers: Array<StatusPageSubscriber> =
|
|
@@ -491,24 +495,111 @@ export class Service extends DatabaseService<Model> {
|
|
|
491
495
|
const createdByUserId: ObjectID | undefined | null =
|
|
492
496
|
createdItem.createdByUserId || createdItem.createdByUser?.id;
|
|
493
497
|
|
|
498
|
+
// send message to workspaces - slack, teams, etc.
|
|
499
|
+
const workspaceResult: {
|
|
500
|
+
channelsCreated: Array<NotificationRuleWorkspaceChannel>;
|
|
501
|
+
} | null =
|
|
502
|
+
await ScheduledMaintenanceWorkspaceMessages.createChannelsAndInviteUsersToChannels(
|
|
503
|
+
{
|
|
504
|
+
projectId: createdItem.projectId!,
|
|
505
|
+
scheduledMaintenanceId: createdItem.id!,
|
|
506
|
+
scheduledMaintenanceNumber: createdItem.scheduledMaintenanceNumber!,
|
|
507
|
+
},
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
if (workspaceResult && workspaceResult.channelsCreated?.length > 0) {
|
|
511
|
+
// update scheduledMaintenance with these channels.
|
|
512
|
+
await this.updateOneById({
|
|
513
|
+
id: createdItem.id!,
|
|
514
|
+
data: {
|
|
515
|
+
postUpdatesToWorkspaceChannels: workspaceResult.channelsCreated || [],
|
|
516
|
+
},
|
|
517
|
+
props: {
|
|
518
|
+
isRoot: true,
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const scheduledMaintenance: Model | null = await this.findOneById({
|
|
524
|
+
id: createdItem.id!,
|
|
525
|
+
select: {
|
|
526
|
+
projectId: true,
|
|
527
|
+
scheduledMaintenanceNumber: true,
|
|
528
|
+
title: true,
|
|
529
|
+
description: true,
|
|
530
|
+
currentScheduledMaintenanceState: {
|
|
531
|
+
name: true,
|
|
532
|
+
},
|
|
533
|
+
startsAt: true,
|
|
534
|
+
endsAt: true,
|
|
535
|
+
monitors: {
|
|
536
|
+
name: true,
|
|
537
|
+
_id: true,
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
props: {
|
|
541
|
+
isRoot: true,
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
if (!scheduledMaintenance) {
|
|
546
|
+
throw new BadDataException("Scheduled Maintenance not found");
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
let feedInfoInMarkdown: string = `#### 🕒 Scheduled Maintenance ${createdItem.scheduledMaintenanceNumber?.toString()} Created:
|
|
550
|
+
|
|
551
|
+
**${createdItem.title || "No title provided."}**:
|
|
552
|
+
|
|
553
|
+
${createdItem.description || "No description provided."}
|
|
554
|
+
|
|
555
|
+
`;
|
|
556
|
+
|
|
557
|
+
// add starts at and ends at.
|
|
558
|
+
if (scheduledMaintenance.startsAt) {
|
|
559
|
+
feedInfoInMarkdown += `**Starts At**: ${OneUptimeDate.getDateAsLocalFormattedString(scheduledMaintenance.startsAt)} \n\n`;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (scheduledMaintenance.endsAt) {
|
|
563
|
+
feedInfoInMarkdown += `**Ends At**: ${OneUptimeDate.getDateAsLocalFormattedString(scheduledMaintenance.endsAt)} \n\n`;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (scheduledMaintenance.currentScheduledMaintenanceState?.name) {
|
|
567
|
+
feedInfoInMarkdown += `⏳ **Scheduled Maintenance State**: ${scheduledMaintenance.currentScheduledMaintenanceState.name} \n\n`;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (
|
|
571
|
+
scheduledMaintenance.monitors &&
|
|
572
|
+
scheduledMaintenance.monitors.length > 0
|
|
573
|
+
) {
|
|
574
|
+
feedInfoInMarkdown += `🌎 **Resources Affected**:\n`;
|
|
575
|
+
|
|
576
|
+
for (const monitor of scheduledMaintenance.monitors) {
|
|
577
|
+
feedInfoInMarkdown += `- [${monitor.name}](${(await MonitorService.getMonitorLinkInDashboard(createdItem.projectId!, monitor.id!)).toString()})\n`;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
feedInfoInMarkdown += `\n\n`;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const scheduledMaintenanceCreateMessageBlocks: Array<MessageBlocksByWorkspaceType> =
|
|
584
|
+
await ScheduledMaintenanceWorkspaceMessages.getScheduledMaintenanceCreateMessageBlocks(
|
|
585
|
+
{
|
|
586
|
+
scheduledMaintenanceId: createdItem.id!,
|
|
587
|
+
projectId: createdItem.projectId!,
|
|
588
|
+
},
|
|
589
|
+
);
|
|
590
|
+
|
|
494
591
|
await ScheduledMaintenanceFeedService.createScheduledMaintenanceFeedItem({
|
|
495
592
|
scheduledMaintenanceId: createdItem.id!,
|
|
496
593
|
projectId: createdItem.projectId!,
|
|
497
594
|
scheduledMaintenanceFeedEventType:
|
|
498
595
|
ScheduledMaintenanceFeedEventType.ScheduledMaintenanceCreated,
|
|
499
596
|
displayColor: Red500,
|
|
500
|
-
feedInfoInMarkdown:
|
|
501
|
-
|
|
502
|
-
**Scheduled Maintenance Title**:
|
|
503
|
-
|
|
504
|
-
${createdItem.title || "No title provided."}
|
|
505
|
-
|
|
506
|
-
**Description**:
|
|
507
|
-
|
|
508
|
-
${createdItem.description || "No description provided."}
|
|
509
|
-
|
|
510
|
-
`,
|
|
597
|
+
feedInfoInMarkdown: feedInfoInMarkdown,
|
|
511
598
|
userId: createdByUserId || undefined,
|
|
599
|
+
workspaceNotification: {
|
|
600
|
+
appendMessageBlocks: scheduledMaintenanceCreateMessageBlocks,
|
|
601
|
+
sendWorkspaceNotification: true,
|
|
602
|
+
},
|
|
512
603
|
});
|
|
513
604
|
|
|
514
605
|
const timeline: ScheduledMaintenanceStateTimeline =
|
|
@@ -1051,5 +1142,277 @@ ${labels
|
|
|
1051
1142
|
},
|
|
1052
1143
|
});
|
|
1053
1144
|
}
|
|
1145
|
+
|
|
1146
|
+
public async isScheduledMaintenanceCompleted(data: {
|
|
1147
|
+
scheduledMaintenanceId: ObjectID;
|
|
1148
|
+
}): Promise<boolean> {
|
|
1149
|
+
const scheduledMaintenance: Model | null = await this.findOneBy({
|
|
1150
|
+
query: {
|
|
1151
|
+
_id: data.scheduledMaintenanceId,
|
|
1152
|
+
},
|
|
1153
|
+
select: {
|
|
1154
|
+
projectId: true,
|
|
1155
|
+
currentScheduledMaintenanceState: {
|
|
1156
|
+
order: true,
|
|
1157
|
+
},
|
|
1158
|
+
},
|
|
1159
|
+
props: {
|
|
1160
|
+
isRoot: true,
|
|
1161
|
+
},
|
|
1162
|
+
});
|
|
1163
|
+
|
|
1164
|
+
if (!scheduledMaintenance) {
|
|
1165
|
+
throw new BadDataException("ScheduledMaintenance not found");
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
if (!scheduledMaintenance.projectId) {
|
|
1169
|
+
throw new BadDataException("Incient Project ID not found");
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
const resolvedScheduledMaintenanceState: ScheduledMaintenanceState =
|
|
1173
|
+
await ScheduledMaintenanceStateService.getCompletedScheduledMaintenanceState(
|
|
1174
|
+
{
|
|
1175
|
+
projectId: scheduledMaintenance.projectId,
|
|
1176
|
+
props: {
|
|
1177
|
+
isRoot: true,
|
|
1178
|
+
},
|
|
1179
|
+
},
|
|
1180
|
+
);
|
|
1181
|
+
|
|
1182
|
+
const currentScheduledMaintenanceStateOrder: number =
|
|
1183
|
+
scheduledMaintenance.currentScheduledMaintenanceState!.order!;
|
|
1184
|
+
const resolvedScheduledMaintenanceStateOrder: number =
|
|
1185
|
+
resolvedScheduledMaintenanceState.order!;
|
|
1186
|
+
|
|
1187
|
+
if (
|
|
1188
|
+
currentScheduledMaintenanceStateOrder >=
|
|
1189
|
+
resolvedScheduledMaintenanceStateOrder
|
|
1190
|
+
) {
|
|
1191
|
+
return true;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
return false;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
public async getScheduledMaintenanceNumber(data: {
|
|
1198
|
+
scheduledMaintenanceId: ObjectID;
|
|
1199
|
+
}): Promise<number | null> {
|
|
1200
|
+
const scheduledMaintenance: Model | null = await this.findOneById({
|
|
1201
|
+
id: data.scheduledMaintenanceId,
|
|
1202
|
+
select: {
|
|
1203
|
+
scheduledMaintenanceNumber: true,
|
|
1204
|
+
},
|
|
1205
|
+
props: {
|
|
1206
|
+
isRoot: true,
|
|
1207
|
+
},
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
if (!scheduledMaintenance) {
|
|
1211
|
+
throw new BadDataException("ScheduledMaintenance not found.");
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
return scheduledMaintenance.scheduledMaintenanceNumber || null;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
public async isScheduledMaintenanceOngoing(data: {
|
|
1218
|
+
scheduledMaintenanceId: ObjectID;
|
|
1219
|
+
}): Promise<boolean> {
|
|
1220
|
+
const scheduledMaintenance: Model | null = await this.findOneBy({
|
|
1221
|
+
query: {
|
|
1222
|
+
_id: data.scheduledMaintenanceId,
|
|
1223
|
+
},
|
|
1224
|
+
select: {
|
|
1225
|
+
projectId: true,
|
|
1226
|
+
currentScheduledMaintenanceState: {
|
|
1227
|
+
order: true,
|
|
1228
|
+
},
|
|
1229
|
+
},
|
|
1230
|
+
props: {
|
|
1231
|
+
isRoot: true,
|
|
1232
|
+
},
|
|
1233
|
+
});
|
|
1234
|
+
|
|
1235
|
+
if (!scheduledMaintenance) {
|
|
1236
|
+
throw new BadDataException("ScheduledMaintenance not found");
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
if (!scheduledMaintenance.projectId) {
|
|
1240
|
+
throw new BadDataException("Incient Project ID not found");
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
const ackScheduledMaintenanceState: ScheduledMaintenanceState =
|
|
1244
|
+
await ScheduledMaintenanceStateService.getOngoingScheduledMaintenanceState(
|
|
1245
|
+
{
|
|
1246
|
+
projectId: scheduledMaintenance.projectId,
|
|
1247
|
+
props: {
|
|
1248
|
+
isRoot: true,
|
|
1249
|
+
},
|
|
1250
|
+
},
|
|
1251
|
+
);
|
|
1252
|
+
|
|
1253
|
+
const currentScheduledMaintenanceStateOrder: number =
|
|
1254
|
+
scheduledMaintenance.currentScheduledMaintenanceState!.order!;
|
|
1255
|
+
const ackScheduledMaintenanceStateOrder: number =
|
|
1256
|
+
ackScheduledMaintenanceState.order!;
|
|
1257
|
+
|
|
1258
|
+
if (
|
|
1259
|
+
currentScheduledMaintenanceStateOrder >= ackScheduledMaintenanceStateOrder
|
|
1260
|
+
) {
|
|
1261
|
+
return true;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
return false;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
public async markScheduledMaintenanceAsComplete(
|
|
1268
|
+
scheduledMaintenanceId: ObjectID,
|
|
1269
|
+
resolvedByUserId: ObjectID,
|
|
1270
|
+
): Promise<Model> {
|
|
1271
|
+
const scheduledMaintenance: Model | null = await this.findOneById({
|
|
1272
|
+
id: scheduledMaintenanceId,
|
|
1273
|
+
select: {
|
|
1274
|
+
projectId: true,
|
|
1275
|
+
scheduledMaintenanceNumber: true,
|
|
1276
|
+
},
|
|
1277
|
+
props: {
|
|
1278
|
+
isRoot: true,
|
|
1279
|
+
},
|
|
1280
|
+
});
|
|
1281
|
+
|
|
1282
|
+
if (!scheduledMaintenance || !scheduledMaintenance.projectId) {
|
|
1283
|
+
throw new BadDataException("ScheduledMaintenance not found.");
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
const scheduledMaintenanceState: ScheduledMaintenanceState | null =
|
|
1287
|
+
await ScheduledMaintenanceStateService.findOneBy({
|
|
1288
|
+
query: {
|
|
1289
|
+
projectId: scheduledMaintenance.projectId,
|
|
1290
|
+
isResolvedState: true,
|
|
1291
|
+
},
|
|
1292
|
+
select: {
|
|
1293
|
+
_id: true,
|
|
1294
|
+
},
|
|
1295
|
+
props: {
|
|
1296
|
+
isRoot: true,
|
|
1297
|
+
},
|
|
1298
|
+
});
|
|
1299
|
+
|
|
1300
|
+
if (!scheduledMaintenanceState || !scheduledMaintenanceState.id) {
|
|
1301
|
+
throw new BadDataException(
|
|
1302
|
+
"Acknowledged state not found for this project. Please add acknowledged state from settings.",
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const scheduledMaintenanceStateTimeline: ScheduledMaintenanceStateTimeline =
|
|
1307
|
+
new ScheduledMaintenanceStateTimeline();
|
|
1308
|
+
scheduledMaintenanceStateTimeline.projectId =
|
|
1309
|
+
scheduledMaintenance.projectId;
|
|
1310
|
+
scheduledMaintenanceStateTimeline.scheduledMaintenanceId =
|
|
1311
|
+
scheduledMaintenanceId;
|
|
1312
|
+
scheduledMaintenanceStateTimeline.scheduledMaintenanceStateId =
|
|
1313
|
+
scheduledMaintenanceState.id;
|
|
1314
|
+
scheduledMaintenanceStateTimeline.createdByUserId = resolvedByUserId;
|
|
1315
|
+
|
|
1316
|
+
await ScheduledMaintenanceStateTimelineService.create({
|
|
1317
|
+
data: scheduledMaintenanceStateTimeline,
|
|
1318
|
+
props: {
|
|
1319
|
+
isRoot: true,
|
|
1320
|
+
},
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
// store scheduledMaintenance metric
|
|
1324
|
+
|
|
1325
|
+
return scheduledMaintenance;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
public async markScheduledMaintenanceAsOngoing(
|
|
1329
|
+
scheduledMaintenanceId: ObjectID,
|
|
1330
|
+
markedByUserId: ObjectID,
|
|
1331
|
+
): Promise<Model> {
|
|
1332
|
+
const scheduledMaintenance: Model | null = await this.findOneById({
|
|
1333
|
+
id: scheduledMaintenanceId,
|
|
1334
|
+
select: {
|
|
1335
|
+
projectId: true,
|
|
1336
|
+
scheduledMaintenanceNumber: true,
|
|
1337
|
+
},
|
|
1338
|
+
props: {
|
|
1339
|
+
isRoot: true,
|
|
1340
|
+
},
|
|
1341
|
+
});
|
|
1342
|
+
|
|
1343
|
+
if (!scheduledMaintenance || !scheduledMaintenance.projectId) {
|
|
1344
|
+
throw new BadDataException("ScheduledMaintenance not found.");
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
const scheduledMaintenanceState: ScheduledMaintenanceState | null =
|
|
1348
|
+
await ScheduledMaintenanceStateService.findOneBy({
|
|
1349
|
+
query: {
|
|
1350
|
+
projectId: scheduledMaintenance.projectId,
|
|
1351
|
+
isOngoingState: true,
|
|
1352
|
+
},
|
|
1353
|
+
select: {
|
|
1354
|
+
_id: true,
|
|
1355
|
+
},
|
|
1356
|
+
props: {
|
|
1357
|
+
isRoot: true,
|
|
1358
|
+
},
|
|
1359
|
+
});
|
|
1360
|
+
|
|
1361
|
+
if (!scheduledMaintenanceState || !scheduledMaintenanceState.id) {
|
|
1362
|
+
throw new BadDataException(
|
|
1363
|
+
"Acknowledged state not found for this project. Please add acknowledged state from settings.",
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
const scheduledMaintenanceStateTimeline: ScheduledMaintenanceStateTimeline =
|
|
1368
|
+
new ScheduledMaintenanceStateTimeline();
|
|
1369
|
+
scheduledMaintenanceStateTimeline.projectId =
|
|
1370
|
+
scheduledMaintenance.projectId;
|
|
1371
|
+
scheduledMaintenanceStateTimeline.scheduledMaintenanceId =
|
|
1372
|
+
scheduledMaintenanceId;
|
|
1373
|
+
scheduledMaintenanceStateTimeline.scheduledMaintenanceStateId =
|
|
1374
|
+
scheduledMaintenanceState.id;
|
|
1375
|
+
scheduledMaintenanceStateTimeline.createdByUserId = markedByUserId;
|
|
1376
|
+
|
|
1377
|
+
await ScheduledMaintenanceStateTimelineService.create({
|
|
1378
|
+
data: scheduledMaintenanceStateTimeline,
|
|
1379
|
+
props: {
|
|
1380
|
+
isRoot: true,
|
|
1381
|
+
},
|
|
1382
|
+
});
|
|
1383
|
+
|
|
1384
|
+
// store scheduledMaintenance metric
|
|
1385
|
+
|
|
1386
|
+
return scheduledMaintenance;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
public async getWorkspaceChannelForScheduledMaintenance(data: {
|
|
1390
|
+
scheduledMaintenanceId: ObjectID;
|
|
1391
|
+
workspaceType?: WorkspaceType | null;
|
|
1392
|
+
}): Promise<Array<NotificationRuleWorkspaceChannel>> {
|
|
1393
|
+
const scheduledMaintenance: Model | null = await this.findOneById({
|
|
1394
|
+
id: data.scheduledMaintenanceId,
|
|
1395
|
+
select: {
|
|
1396
|
+
postUpdatesToWorkspaceChannels: true,
|
|
1397
|
+
},
|
|
1398
|
+
props: {
|
|
1399
|
+
isRoot: true,
|
|
1400
|
+
},
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
if (!scheduledMaintenance) {
|
|
1404
|
+
throw new BadDataException("ScheduledMaintenance not found.");
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
return (scheduledMaintenance.postUpdatesToWorkspaceChannels || []).filter(
|
|
1408
|
+
(channel: NotificationRuleWorkspaceChannel) => {
|
|
1409
|
+
if (!data.workspaceType) {
|
|
1410
|
+
return true;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
return channel.workspaceType === data.workspaceType;
|
|
1414
|
+
},
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1054
1417
|
}
|
|
1055
1418
|
export default new Service();
|
|
@@ -8,22 +8,27 @@ import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
|
8
8
|
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
9
9
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
10
10
|
import ObjectID from "../../Types/ObjectID";
|
|
11
|
-
import
|
|
11
|
+
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
12
|
+
import ScheduledMaintenanceState from "Common/Models/DatabaseModels/ScheduledMaintenanceState";
|
|
12
13
|
|
|
13
|
-
export class Service extends DatabaseService<
|
|
14
|
+
export class Service extends DatabaseService<ScheduledMaintenanceState> {
|
|
14
15
|
public constructor() {
|
|
15
|
-
super(
|
|
16
|
+
super(ScheduledMaintenanceState);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
protected override async onBeforeCreate(
|
|
19
|
-
createBy: CreateBy<
|
|
20
|
-
): Promise<OnCreate<
|
|
20
|
+
createBy: CreateBy<ScheduledMaintenanceState>,
|
|
21
|
+
): Promise<OnCreate<ScheduledMaintenanceState>> {
|
|
21
22
|
if (!createBy.data.order) {
|
|
22
|
-
throw new BadDataException(
|
|
23
|
+
throw new BadDataException(
|
|
24
|
+
"ScheduledMaintenance State order is required",
|
|
25
|
+
);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
if (!createBy.data.projectId) {
|
|
26
|
-
throw new BadDataException(
|
|
29
|
+
throw new BadDataException(
|
|
30
|
+
"ScheduledMaintenance State projectId is required",
|
|
31
|
+
);
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
await this.rearrangeOrder(
|
|
@@ -39,15 +44,15 @@ export class Service extends DatabaseService<Model> {
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
protected override async onBeforeDelete(
|
|
42
|
-
deleteBy: DeleteBy<
|
|
43
|
-
): Promise<OnDelete<
|
|
47
|
+
deleteBy: DeleteBy<ScheduledMaintenanceState>,
|
|
48
|
+
): Promise<OnDelete<ScheduledMaintenanceState>> {
|
|
44
49
|
if (!deleteBy.query._id && !deleteBy.props.isRoot) {
|
|
45
50
|
throw new BadDataException(
|
|
46
51
|
"_id should be present when deleting scheduled maintenance states. Please try the delete with objectId",
|
|
47
52
|
);
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
let scheduledMaintenanceState:
|
|
55
|
+
let scheduledMaintenanceState: ScheduledMaintenanceState | null = null;
|
|
51
56
|
|
|
52
57
|
if (!deleteBy.props.isRoot) {
|
|
53
58
|
scheduledMaintenanceState = await this.findOneBy({
|
|
@@ -69,11 +74,12 @@ export class Service extends DatabaseService<Model> {
|
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
protected override async onDeleteSuccess(
|
|
72
|
-
onDelete: OnDelete<
|
|
77
|
+
onDelete: OnDelete<ScheduledMaintenanceState>,
|
|
73
78
|
_itemIdsBeforeDelete: ObjectID[],
|
|
74
|
-
): Promise<OnDelete<
|
|
75
|
-
const deleteBy: DeleteBy<
|
|
76
|
-
const scheduledMaintenanceState:
|
|
79
|
+
): Promise<OnDelete<ScheduledMaintenanceState>> {
|
|
80
|
+
const deleteBy: DeleteBy<ScheduledMaintenanceState> = onDelete.deleteBy;
|
|
81
|
+
const scheduledMaintenanceState: ScheduledMaintenanceState | null =
|
|
82
|
+
onDelete.carryForward;
|
|
77
83
|
|
|
78
84
|
if (!deleteBy.props.isRoot && scheduledMaintenanceState) {
|
|
79
85
|
if (
|
|
@@ -96,8 +102,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
protected override async onBeforeUpdate(
|
|
99
|
-
updateBy: UpdateBy<
|
|
100
|
-
): Promise<OnUpdate<
|
|
105
|
+
updateBy: UpdateBy<ScheduledMaintenanceState>,
|
|
106
|
+
): Promise<OnUpdate<ScheduledMaintenanceState>> {
|
|
101
107
|
if (updateBy.data.order && !updateBy.props.isRoot) {
|
|
102
108
|
throw new BadDataException(
|
|
103
109
|
"Scheduled Maintenance State order should not be updated. Delete this scheduled maintenance state and create a new state with the right order.",
|
|
@@ -113,24 +119,25 @@ export class Service extends DatabaseService<Model> {
|
|
|
113
119
|
increaseOrder: boolean = true,
|
|
114
120
|
): Promise<void> {
|
|
115
121
|
// get scheduledMaintenance with this order.
|
|
116
|
-
const scheduledMaintenanceStates: Array<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
122
|
+
const scheduledMaintenanceStates: Array<ScheduledMaintenanceState> =
|
|
123
|
+
await this.findBy({
|
|
124
|
+
query: {
|
|
125
|
+
order: QueryHelper.greaterThanEqualTo(currentOrder),
|
|
126
|
+
projectId: projectId,
|
|
127
|
+
},
|
|
128
|
+
limit: LIMIT_MAX,
|
|
129
|
+
skip: 0,
|
|
130
|
+
props: {
|
|
131
|
+
isRoot: true,
|
|
132
|
+
},
|
|
133
|
+
select: {
|
|
134
|
+
_id: true,
|
|
135
|
+
order: true,
|
|
136
|
+
},
|
|
137
|
+
sort: {
|
|
138
|
+
order: SortOrder.Ascending,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
134
141
|
|
|
135
142
|
let newOrder: number = currentOrder;
|
|
136
143
|
|
|
@@ -154,5 +161,86 @@ export class Service extends DatabaseService<Model> {
|
|
|
154
161
|
});
|
|
155
162
|
}
|
|
156
163
|
}
|
|
164
|
+
|
|
165
|
+
public async getCompletedScheduledMaintenanceState(data: {
|
|
166
|
+
projectId: ObjectID;
|
|
167
|
+
props: DatabaseCommonInteractionProps;
|
|
168
|
+
}): Promise<ScheduledMaintenanceState> {
|
|
169
|
+
const scheduledMaintenanceStates: Array<ScheduledMaintenanceState> =
|
|
170
|
+
await this.getAllScheduledMaintenanceStates({
|
|
171
|
+
projectId: data.projectId,
|
|
172
|
+
props: data.props,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const resolvedScheduledMaintenanceState:
|
|
176
|
+
| ScheduledMaintenanceState
|
|
177
|
+
| undefined = scheduledMaintenanceStates.find(
|
|
178
|
+
(scheduledMaintenanceState: ScheduledMaintenanceState) => {
|
|
179
|
+
return scheduledMaintenanceState?.isResolvedState;
|
|
180
|
+
},
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
if (!resolvedScheduledMaintenanceState) {
|
|
184
|
+
throw new BadDataException(
|
|
185
|
+
"Completed ScheduledMaintenance State not found for this project",
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return resolvedScheduledMaintenanceState;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public async getAllScheduledMaintenanceStates(data: {
|
|
193
|
+
projectId: ObjectID;
|
|
194
|
+
props: DatabaseCommonInteractionProps;
|
|
195
|
+
}): Promise<Array<ScheduledMaintenanceState>> {
|
|
196
|
+
const scheduledMaintenanceStates: Array<ScheduledMaintenanceState> =
|
|
197
|
+
await this.findBy({
|
|
198
|
+
query: {
|
|
199
|
+
projectId: data.projectId,
|
|
200
|
+
},
|
|
201
|
+
skip: 0,
|
|
202
|
+
limit: LIMIT_MAX,
|
|
203
|
+
sort: {
|
|
204
|
+
order: SortOrder.Ascending,
|
|
205
|
+
},
|
|
206
|
+
select: {
|
|
207
|
+
_id: true,
|
|
208
|
+
isResolvedState: true,
|
|
209
|
+
isOngoingState: true,
|
|
210
|
+
isScheduledState: true,
|
|
211
|
+
order: true,
|
|
212
|
+
name: true,
|
|
213
|
+
},
|
|
214
|
+
props: data.props,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
return scheduledMaintenanceStates;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
public async getOngoingScheduledMaintenanceState(data: {
|
|
221
|
+
projectId: ObjectID;
|
|
222
|
+
props: DatabaseCommonInteractionProps;
|
|
223
|
+
}): Promise<ScheduledMaintenanceState> {
|
|
224
|
+
const scheduledMaintenanceStates: Array<ScheduledMaintenanceState> =
|
|
225
|
+
await this.getAllScheduledMaintenanceStates({
|
|
226
|
+
projectId: data.projectId,
|
|
227
|
+
props: data.props,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const ackScheduledMaintenanceState: ScheduledMaintenanceState | undefined =
|
|
231
|
+
scheduledMaintenanceStates.find(
|
|
232
|
+
(scheduledMaintenanceState: ScheduledMaintenanceState) => {
|
|
233
|
+
return scheduledMaintenanceState?.isOngoingState;
|
|
234
|
+
},
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
if (!ackScheduledMaintenanceState) {
|
|
238
|
+
throw new BadDataException(
|
|
239
|
+
"Ongoing ScheduledMaintenance State not found for this project",
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return ackScheduledMaintenanceState;
|
|
244
|
+
}
|
|
157
245
|
}
|
|
158
246
|
export default new Service();
|
|
@@ -150,11 +150,35 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
150
150
|
_id: true,
|
|
151
151
|
color: true,
|
|
152
152
|
name: true,
|
|
153
|
+
isResolvedState: true,
|
|
154
|
+
isOngoingState: true,
|
|
155
|
+
isScheduledState: true,
|
|
153
156
|
},
|
|
154
157
|
});
|
|
155
158
|
|
|
156
159
|
const stateName: string = scheduledMaintenanceState?.name || "";
|
|
157
160
|
|
|
161
|
+
const scheduledMaintenanceNumber: number | null =
|
|
162
|
+
await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
|
|
163
|
+
scheduledMaintenanceId: createdItem.scheduledMaintenanceId,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// if resolved state then change emoji to ✅.
|
|
167
|
+
let stateEmoji: string = "➡️";
|
|
168
|
+
|
|
169
|
+
if (scheduledMaintenanceState?.isResolvedState) {
|
|
170
|
+
stateEmoji = "✅";
|
|
171
|
+
} else if (scheduledMaintenanceState?.isOngoingState) {
|
|
172
|
+
// eyes emoji for acknowledged state.
|
|
173
|
+
stateEmoji = "⏳";
|
|
174
|
+
} else if (scheduledMaintenanceState?.isScheduledState) {
|
|
175
|
+
stateEmoji = "🕒";
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const projectId: ObjectID = createdItem.projectId!;
|
|
179
|
+
const scheduledMaintenanceId: ObjectID =
|
|
180
|
+
createdItem.scheduledMaintenanceId!;
|
|
181
|
+
|
|
158
182
|
await ScheduledMaintenanceFeedService.createScheduledMaintenanceFeedItem({
|
|
159
183
|
scheduledMaintenanceId: createdItem.scheduledMaintenanceId!,
|
|
160
184
|
projectId: createdItem.projectId!,
|
|
@@ -162,8 +186,16 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
162
186
|
ScheduledMaintenanceFeedEventType.ScheduledMaintenanceStateChanged,
|
|
163
187
|
displayColor: scheduledMaintenanceState?.color,
|
|
164
188
|
feedInfoInMarkdown:
|
|
165
|
-
|
|
189
|
+
stateEmoji +
|
|
190
|
+
` Changed **[Scheduled Maintenance ${scheduledMaintenanceNumber}](${(await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(projectId!, scheduledMaintenanceId!)).toString()}) State** to **` +
|
|
191
|
+
stateName +
|
|
192
|
+
"**",
|
|
166
193
|
userId: createdItem.createdByUserId || onCreate.createBy.props.userId,
|
|
194
|
+
workspaceNotification: {
|
|
195
|
+
sendWorkspaceNotification: true,
|
|
196
|
+
notifyUserId:
|
|
197
|
+
createdItem.createdByUserId || onCreate.createBy.props.userId,
|
|
198
|
+
},
|
|
167
199
|
});
|
|
168
200
|
|
|
169
201
|
// TODO: DELETE THIS WHEN WORKFLOW IS IMPLEMENMTED.
|