@oneuptime/common 7.0.3786 → 7.0.3822

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.
Files changed (137) hide show
  1. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -1
  2. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -1
  3. package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -1
  4. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -1
  5. package/Models/DatabaseModels/WorkspaceNotificationRule.ts +8 -0
  6. package/Server/API/SlackAPI.ts +68 -0
  7. package/Server/Services/AccessTokenService.ts +21 -0
  8. package/Server/Services/AlertFeedService.ts +98 -0
  9. package/Server/Services/AlertInternalNoteService.ts +49 -8
  10. package/Server/Services/AlertOwnerTeamService.ts +50 -2
  11. package/Server/Services/AlertOwnerUserService.ts +52 -2
  12. package/Server/Services/AlertService.ts +236 -37
  13. package/Server/Services/AlertStateService.ts +24 -0
  14. package/Server/Services/AlertStateTimelineService.ts +30 -2
  15. package/Server/Services/IncidentInternalNoteService.ts +6 -6
  16. package/Server/Services/IncidentPublicNoteService.ts +7 -4
  17. package/Server/Services/IncidentStateTimelineService.ts +2 -1
  18. package/Server/Services/MonitorStatusTimelineService.ts +202 -101
  19. package/Server/Services/ScheduledMaintenanceFeedService.ts +103 -0
  20. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +50 -6
  21. package/Server/Services/ScheduledMaintenanceOwnerTeamService.ts +37 -0
  22. package/Server/Services/ScheduledMaintenanceOwnerUserService.ts +34 -0
  23. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +49 -7
  24. package/Server/Services/ScheduledMaintenanceService.ts +375 -12
  25. package/Server/Services/ScheduledMaintenanceStateService.ts +122 -34
  26. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +33 -1
  27. package/Server/Services/WorkspaceNotificationRuleService.ts +12 -0
  28. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.ts +38 -0
  29. package/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.ts +116 -0
  30. package/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.ts +36 -115
  31. package/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.ts +108 -0
  32. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +20 -2
  33. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +697 -0
  34. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +9 -2
  35. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +9 -3
  36. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +956 -0
  37. package/Server/Utils/Workspace/Slack/Messages/Alert.ts +116 -0
  38. package/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.ts +108 -0
  39. package/Server/Utils/Workspace/Slack/Slack.ts +48 -2
  40. package/Server/Utils/Workspace/Slack/app-manifest.json +3 -3
  41. package/Server/Utils/Workspace/WorkspaceBase.ts +14 -0
  42. package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +69 -0
  43. package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +73 -0
  44. package/Types/Date.ts +5 -0
  45. package/Types/Workspace/WorkspaceMessagePayload.ts +9 -0
  46. package/UI/Components/Forms/BasicForm.tsx +4 -0
  47. package/UI/Components/Forms/Types/Field.ts +3 -0
  48. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -1
  49. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  50. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -1
  51. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  52. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -1
  53. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  54. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -1
  55. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  56. package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js +8 -0
  57. package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js.map +1 -1
  58. package/build/dist/Server/API/SlackAPI.js +54 -0
  59. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  60. package/build/dist/Server/Services/AccessTokenService.js +11 -0
  61. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  62. package/build/dist/Server/Services/AlertFeedService.js +60 -0
  63. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  64. package/build/dist/Server/Services/AlertInternalNoteService.js +39 -8
  65. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  66. package/build/dist/Server/Services/AlertOwnerTeamService.js +40 -2
  67. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
  68. package/build/dist/Server/Services/AlertOwnerUserService.js +41 -3
  69. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
  70. package/build/dist/Server/Services/AlertService.js +192 -35
  71. package/build/dist/Server/Services/AlertService.js.map +1 -1
  72. package/build/dist/Server/Services/AlertStateService.js +13 -0
  73. package/build/dist/Server/Services/AlertStateService.js.map +1 -1
  74. package/build/dist/Server/Services/AlertStateTimelineService.js +26 -2
  75. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  76. package/build/dist/Server/Services/IncidentInternalNoteService.js +6 -6
  77. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  78. package/build/dist/Server/Services/IncidentPublicNoteService.js +5 -4
  79. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  80. package/build/dist/Server/Services/IncidentStateTimelineService.js +1 -1
  81. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  82. package/build/dist/Server/Services/MonitorStatusTimelineService.js +168 -72
  83. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  84. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js +60 -0
  85. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js.map +1 -1
  86. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +36 -6
  87. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  88. package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js +24 -0
  89. package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js.map +1 -1
  90. package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js +22 -0
  91. package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js.map +1 -1
  92. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +36 -7
  93. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  94. package/build/dist/Server/Services/ScheduledMaintenanceService.js +275 -13
  95. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  96. package/build/dist/Server/Services/ScheduledMaintenanceStateService.js +52 -4
  97. package/build/dist/Server/Services/ScheduledMaintenanceStateService.js.map +1 -1
  98. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +28 -1
  99. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  100. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +10 -0
  101. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  102. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js +37 -0
  103. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js.map +1 -0
  104. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.js +82 -0
  105. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.js.map +1 -0
  106. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js +33 -99
  107. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js.map +1 -1
  108. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.js +74 -0
  109. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.js.map +1 -0
  110. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +20 -2
  111. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  112. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +425 -0
  113. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -0
  114. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +2 -0
  115. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
  116. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +5 -2
  117. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  118. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +599 -0
  119. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -0
  120. package/build/dist/Server/Utils/Workspace/Slack/Messages/Alert.js +82 -0
  121. package/build/dist/Server/Utils/Workspace/Slack/Messages/Alert.js.map +1 -0
  122. package/build/dist/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.js +74 -0
  123. package/build/dist/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.js.map +1 -0
  124. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +34 -0
  125. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  126. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +3 -3
  127. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +8 -0
  128. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  129. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js +48 -0
  130. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -0
  131. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js +47 -0
  132. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -0
  133. package/build/dist/Types/Date.js +4 -0
  134. package/build/dist/Types/Date.js.map +1 -1
  135. package/build/dist/UI/Components/Forms/BasicForm.js +3 -0
  136. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  137. package/package.json +2 -2
@@ -8,6 +8,11 @@ import UserService from "./UserService";
8
8
  import ScheduledMaintenanceFeedService from "./ScheduledMaintenanceFeedService";
9
9
  import { ScheduledMaintenanceFeedEventType } from "../../Models/DatabaseModels/ScheduledMaintenanceFeed";
10
10
  import { Gray500, Red500 } from "../../Types/BrandColors";
11
+ import WorkspaceNotificationRule from "../../Models/DatabaseModels/WorkspaceNotificationRule";
12
+ import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
13
+ import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
14
+ import ScheduledMaintenanceService from "./ScheduledMaintenanceService";
15
+ import logger from "../Utils/Logger";
11
16
 
12
17
  export class Service extends DatabaseService<Model> {
13
18
  public constructor() {
@@ -119,6 +124,35 @@ export class Service extends DatabaseService<Model> {
119
124
  }
120
125
  }
121
126
 
127
+ // get notification rule where inviteOwners is true.
128
+ const notificationRules: Array<WorkspaceNotificationRule> =
129
+ await WorkspaceNotificationRuleService.getNotificationRulesWhereInviteOwnersIsTrue(
130
+ {
131
+ projectId: projectId!,
132
+ notificationFor: {
133
+ scheduledMaintenanceId: scheduledMaintenanceId,
134
+ },
135
+ notificationRuleEventType:
136
+ NotificationRuleEventType.ScheduledMaintenance,
137
+ },
138
+ );
139
+
140
+ WorkspaceNotificationRuleService.inviteUsersBasedOnRulesAndWorkspaceChannels(
141
+ {
142
+ notificationRules: notificationRules,
143
+ projectId: projectId!,
144
+ workspaceChannels:
145
+ await ScheduledMaintenanceService.getWorkspaceChannelForScheduledMaintenance(
146
+ {
147
+ scheduledMaintenanceId: scheduledMaintenanceId!,
148
+ },
149
+ ),
150
+ userIds: [userId!],
151
+ },
152
+ ).catch((error: Error) => {
153
+ logger.error(error);
154
+ });
155
+
122
156
  return createdItem;
123
157
  }
124
158
  }
@@ -8,6 +8,8 @@ import ObjectID from "../../Types/ObjectID";
8
8
  import { ScheduledMaintenanceFeedEventType } from "../../Models/DatabaseModels/ScheduledMaintenanceFeed";
9
9
  import { Blue500, Indigo500 } from "../../Types/BrandColors";
10
10
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
11
+ import ScheduledMaintenanceService from "./ScheduledMaintenanceService";
12
+ import ScheduledMaintenance from "../../Models/DatabaseModels/ScheduledMaintenance";
11
13
 
12
14
  export class Service extends DatabaseService<Model> {
13
15
  public constructor() {
@@ -34,6 +36,14 @@ export class Service extends DatabaseService<Model> {
34
36
  const userId: ObjectID | null | undefined =
35
37
  createdItem.createdByUserId || createdItem.createdByUser?.id;
36
38
 
39
+ const scheduledMaintenanceId: ObjectID =
40
+ createdItem.scheduledMaintenanceId!;
41
+ const projectId: ObjectID = createdItem.projectId!;
42
+ const scheduledMaintenanceNumber: number | null =
43
+ await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
44
+ scheduledMaintenanceId: scheduledMaintenanceId,
45
+ });
46
+
37
47
  await ScheduledMaintenanceFeedService.createScheduledMaintenanceFeedItem({
38
48
  scheduledMaintenanceId: createdItem.scheduledMaintenanceId!,
39
49
  projectId: createdItem.projectId!,
@@ -41,10 +51,14 @@ export class Service extends DatabaseService<Model> {
41
51
  ScheduledMaintenanceFeedEventType.PublicNote,
42
52
  displayColor: Indigo500,
43
53
  userId: userId || undefined,
44
- feedInfoInMarkdown: `**Posted public note for this scheduled maintenance on status page**
45
-
54
+ feedInfoInMarkdown: `📄 posted **public note** for this [Scheduled Maintenance ${scheduledMaintenanceNumber}](${(await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(projectId!, scheduledMaintenanceId!)).toString()}) on status page:
55
+
46
56
  ${createdItem.note}
47
- `,
57
+ `,
58
+ workspaceNotification: {
59
+ sendWorkspaceNotification: true,
60
+ notifyUserId: userId || undefined,
61
+ },
48
62
  });
49
63
 
50
64
  return createdItem;
@@ -77,25 +91,53 @@ ${createdItem.note}
77
91
  onUpdate.updateBy.props.userId;
78
92
 
79
93
  for (const updatedItem of updatedItems) {
94
+ const scheduledMaintenance: ScheduledMaintenance =
95
+ updatedItem.scheduledMaintenance!;
96
+
80
97
  await ScheduledMaintenanceFeedService.createScheduledMaintenanceFeedItem(
81
98
  {
82
99
  scheduledMaintenanceId: updatedItem.scheduledMaintenanceId!,
83
100
  projectId: updatedItem.projectId!,
84
101
  scheduledMaintenanceFeedEventType:
85
- ScheduledMaintenanceFeedEventType.PublicNote,
102
+ ScheduledMaintenanceFeedEventType.PrivateNote,
86
103
  displayColor: Blue500,
87
104
  userId: userId || undefined,
88
105
 
89
- feedInfoInMarkdown: `**Updated Public Note**
90
-
106
+ feedInfoInMarkdown: `📄 updated **Public Note** for this [Scheduled Maintenance ${scheduledMaintenance.scheduledMaintenanceNumber}](${(await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(scheduledMaintenance.projectId!, scheduledMaintenance.id!)).toString()})
107
+
91
108
  ${updatedItem.note}
92
- `,
109
+ `,
110
+ workspaceNotification: {
111
+ sendWorkspaceNotification: true,
112
+ notifyUserId: userId || undefined,
113
+ },
93
114
  },
94
115
  );
95
116
  }
96
117
  }
97
118
  return onUpdate;
98
119
  }
120
+
121
+ public async addNote(data: {
122
+ userId: ObjectID;
123
+ scheduledMaintenanceId: ObjectID;
124
+ projectId: ObjectID;
125
+ note: string;
126
+ }): Promise<Model> {
127
+ const publicNote: Model = new Model();
128
+ publicNote.createdByUserId = data.userId;
129
+ publicNote.scheduledMaintenanceId = data.scheduledMaintenanceId;
130
+ publicNote.projectId = data.projectId;
131
+ publicNote.note = data.note;
132
+ publicNote.postedAt = OneUptimeDate.getCurrentDate();
133
+
134
+ return this.create({
135
+ data: publicNote,
136
+ props: {
137
+ isRoot: true,
138
+ },
139
+ });
140
+ }
99
141
  }
100
142
 
101
143
  export default new Service();
@@ -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 incidents are not visible on status page.
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: `**Scheduled Maintenance #${createdItem.scheduledMaintenanceNumber?.toString()} Created**:
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();