@oneuptime/common 9.5.7 → 9.5.9
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/Alert.ts +8 -9
- package/Models/DatabaseModels/Incident.ts +5 -5
- package/Models/DatabaseModels/IncidentTemplate.ts +4 -3
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +1 -1
- package/Models/DatabaseModels/UserOnCallLog.ts +1 -1
- package/Models/DatabaseModels/UserPush.ts +2 -1
- package/Server/API/UserPushAPI.ts +51 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1770833704656-MigrationName.ts +156 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1770834237090-MigrationName.ts +119 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/UserAuthorization.ts +14 -9
- package/Server/Services/AlertEpisodeFeedService.ts +50 -0
- package/Server/Services/AlertEpisodeInternalNoteService.ts +162 -0
- package/Server/Services/AlertEpisodeMemberService.ts +7 -0
- package/Server/Services/AlertEpisodeOwnerTeamService.ts +186 -0
- package/Server/Services/AlertEpisodeOwnerUserService.ts +180 -0
- package/Server/Services/AlertEpisodeService.ts +68 -0
- package/Server/Services/AlertEpisodeStateTimelineService.ts +5 -0
- package/Server/Services/AlertService.ts +3 -0
- package/Server/Services/IncidentEpisodeFeedService.ts +50 -0
- package/Server/Services/IncidentEpisodeInternalNoteService.ts +163 -0
- package/Server/Services/IncidentEpisodeMemberService.ts +7 -0
- package/Server/Services/IncidentEpisodeOwnerTeamService.ts +189 -0
- package/Server/Services/IncidentEpisodeOwnerUserService.ts +183 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +8 -0
- package/Server/Services/IncidentEpisodeService.ts +91 -12
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +5 -0
- package/Server/Services/IncidentService.ts +5 -0
- package/Server/Services/PushNotificationService.ts +129 -27
- package/Server/Services/UserNotificationRuleService.ts +13 -3
- package/Server/Services/UserPushService.ts +2 -1
- package/Server/Services/WorkspaceNotificationRuleService.ts +20 -0
- package/Server/Utils/PushNotificationUtil.ts +56 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +1 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +7 -6
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +1 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +7 -6
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +17 -0
- package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +27 -12
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +17 -0
- package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +86 -28
- package/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.ts +6 -6
- package/Server/Utils/Workspace/Slack/Slack.ts +49 -0
- package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +2 -1
- package/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.ts +3 -1
- package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +2 -1
- package/Server/Utils/Workspace/WorkspaceMessages/IncidentEpisode.ts +3 -1
- package/Types/Permission.ts +641 -0
- package/Types/PushNotification/PushDeviceType.ts +7 -0
- package/Types/PushNotification/PushNotificationRequest.ts +3 -1
- package/UI/Components/Detail/Detail.tsx +13 -4
- package/UI/Components/Detail/Field.ts +2 -2
- package/UI/Components/Dropdown/Dropdown.tsx +38 -7
- package/UI/Components/Forms/BasicForm.tsx +35 -5
- package/UI/Components/Forms/Fields/PermissionPicker.tsx +261 -0
- package/UI/Components/Forms/Types/Field.ts +5 -3
- package/UI/Components/ModelDelete/ModelDelete.tsx +4 -1
- package/UI/Components/ModelDetail/CardModelDetail.tsx +4 -0
- package/UI/Components/ModelDetail/ModelDetail.tsx +4 -1
- package/UI/Components/Page/ModelPage.tsx +4 -1
- package/UI/Utils/Permission.ts +29 -6
- package/build/dist/Models/DatabaseModels/Alert.js +8 -8
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +5 -5
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +3 -3
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +2 -1
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Server/API/UserPushAPI.js +34 -3
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770833704656-MigrationName.js +63 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770833704656-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770834237090-MigrationName.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770834237090-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/Middleware/UserAuthorization.js +10 -4
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeFeedService.js +33 -0
- package/build/dist/Server/Services/AlertEpisodeFeedService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js +132 -0
- package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeMemberService.js +7 -0
- package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js +163 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js +156 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +53 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +4 -0
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +3 -5
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeFeedService.js +33 -0
- package/build/dist/Server/Services/IncidentEpisodeFeedService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeInternalNoteService.js +132 -0
- package/build/dist/Server/Services/IncidentEpisodeInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +7 -0
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerTeamService.js +163 -0
- package/build/dist/Server/Services/IncidentEpisodeOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerUserService.js +156 -0
- package/build/dist/Server/Services/IncidentEpisodeOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +8 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +72 -10
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +4 -0
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +5 -5
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +77 -21
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +12 -9
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +2 -1
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +16 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Utils/PushNotificationUtil.js +32 -8
- package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +7 -6
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +7 -6
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +16 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +25 -9
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +16 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +71 -25
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.js +6 -6
- package/build/dist/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +40 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/IncidentEpisode.js +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/IncidentEpisode.js.map +1 -1
- package/build/dist/Types/Permission.js +637 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/PushDeviceType.js +8 -0
- package/build/dist/Types/PushNotification/PushDeviceType.js.map +1 -0
- package/build/dist/UI/Components/Detail/Detail.js +7 -1
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +17 -2
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +17 -3
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/PermissionPicker.js +129 -0
- package/build/dist/UI/Components/Forms/Fields/PermissionPicker.js.map +1 -0
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js +2 -1
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js +2 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +2 -1
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Utils/Permission.js +17 -4
- package/build/dist/UI/Utils/Permission.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import ObjectID from "../../Types/ObjectID";
|
|
2
2
|
import DatabaseService from "./DatabaseService";
|
|
3
3
|
import Model from "../../Models/DatabaseModels/AlertEpisodeInternalNote";
|
|
4
|
+
import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
|
|
5
|
+
import AlertEpisodeFeedService from "./AlertEpisodeFeedService";
|
|
6
|
+
import { AlertEpisodeFeedEventType } from "../../Models/DatabaseModels/AlertEpisodeFeed";
|
|
7
|
+
import { Blue500 } from "../../Types/BrandColors";
|
|
8
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
9
|
+
import AlertEpisodeService from "./AlertEpisodeService";
|
|
10
|
+
import AlertEpisode from "../../Models/DatabaseModels/AlertEpisode";
|
|
4
11
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
5
12
|
import File from "../../Models/DatabaseModels/File";
|
|
13
|
+
import FileAttachmentMarkdownUtil from "../Utils/FileAttachmentMarkdownUtil";
|
|
6
14
|
|
|
7
15
|
export class Service extends DatabaseService<Model> {
|
|
8
16
|
public constructor() {
|
|
@@ -66,6 +74,160 @@ export class Service extends DatabaseService<Model> {
|
|
|
66
74
|
|
|
67
75
|
return existingNote !== null;
|
|
68
76
|
}
|
|
77
|
+
|
|
78
|
+
@CaptureSpan()
|
|
79
|
+
public override async onCreateSuccess(
|
|
80
|
+
_onCreate: OnCreate<Model>,
|
|
81
|
+
createdItem: Model,
|
|
82
|
+
): Promise<Model> {
|
|
83
|
+
const userId: ObjectID | null | undefined =
|
|
84
|
+
createdItem.createdByUserId || createdItem.createdByUser?.id;
|
|
85
|
+
|
|
86
|
+
const alertEpisodeId: ObjectID = createdItem.alertEpisodeId!;
|
|
87
|
+
|
|
88
|
+
const episodeNumberResult: {
|
|
89
|
+
number: number | null;
|
|
90
|
+
numberWithPrefix: string | null;
|
|
91
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
92
|
+
episodeId: alertEpisodeId,
|
|
93
|
+
});
|
|
94
|
+
const episodeNumberDisplay: string =
|
|
95
|
+
episodeNumberResult.numberWithPrefix || "#" + episodeNumberResult.number;
|
|
96
|
+
|
|
97
|
+
const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
|
|
98
|
+
createdItem.id!,
|
|
99
|
+
"/alert-episode-internal-note/attachment",
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
103
|
+
alertEpisodeId: createdItem.alertEpisodeId!,
|
|
104
|
+
projectId: createdItem.projectId!,
|
|
105
|
+
alertEpisodeFeedEventType: AlertEpisodeFeedEventType.PrivateNote,
|
|
106
|
+
displayColor: Blue500,
|
|
107
|
+
userId: userId || undefined,
|
|
108
|
+
feedInfoInMarkdown: `📄 posted **private note** for this [Episode ${episodeNumberDisplay}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId!, alertEpisodeId)).toString()}):
|
|
109
|
+
|
|
110
|
+
${(createdItem.note || "") + attachmentsMarkdown}
|
|
111
|
+
`,
|
|
112
|
+
workspaceNotification: {
|
|
113
|
+
sendWorkspaceNotification: true,
|
|
114
|
+
notifyUserId: userId || undefined,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return createdItem;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@CaptureSpan()
|
|
122
|
+
public override async onUpdateSuccess(
|
|
123
|
+
onUpdate: OnUpdate<Model>,
|
|
124
|
+
_updatedItemIds: Array<ObjectID>,
|
|
125
|
+
): Promise<OnUpdate<Model>> {
|
|
126
|
+
if (onUpdate.updateBy.data.note) {
|
|
127
|
+
const updatedItems: Array<Model> = await this.findBy({
|
|
128
|
+
query: onUpdate.updateBy.query,
|
|
129
|
+
limit: LIMIT_PER_PROJECT,
|
|
130
|
+
skip: 0,
|
|
131
|
+
props: {
|
|
132
|
+
isRoot: true,
|
|
133
|
+
},
|
|
134
|
+
select: {
|
|
135
|
+
alertEpisodeId: true,
|
|
136
|
+
alertEpisode: {
|
|
137
|
+
projectId: true,
|
|
138
|
+
episodeNumber: true,
|
|
139
|
+
episodeNumberWithPrefix: true,
|
|
140
|
+
},
|
|
141
|
+
projectId: true,
|
|
142
|
+
note: true,
|
|
143
|
+
createdByUserId: true,
|
|
144
|
+
createdByUser: {
|
|
145
|
+
_id: true,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const userId: ObjectID | null | undefined =
|
|
151
|
+
onUpdate.updateBy.props.userId;
|
|
152
|
+
|
|
153
|
+
for (const updatedItem of updatedItems) {
|
|
154
|
+
const episode: AlertEpisode = updatedItem.alertEpisode!;
|
|
155
|
+
|
|
156
|
+
const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
|
|
157
|
+
updatedItem.id!,
|
|
158
|
+
"/alert-episode-internal-note/attachment",
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
162
|
+
alertEpisodeId: updatedItem.alertEpisodeId!,
|
|
163
|
+
projectId: updatedItem.projectId!,
|
|
164
|
+
alertEpisodeFeedEventType: AlertEpisodeFeedEventType.PrivateNote,
|
|
165
|
+
displayColor: Blue500,
|
|
166
|
+
userId: userId || undefined,
|
|
167
|
+
feedInfoInMarkdown: `📄 updated **Private Note** for this [Episode ${episode.episodeNumberWithPrefix || "#" + episode.episodeNumber}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(episode.projectId!, episode.id!)).toString()})
|
|
168
|
+
|
|
169
|
+
${(updatedItem.note || "") + attachmentsMarkdown}
|
|
170
|
+
`,
|
|
171
|
+
workspaceNotification: {
|
|
172
|
+
sendWorkspaceNotification: true,
|
|
173
|
+
notifyUserId: userId || undefined,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return onUpdate;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private async getAttachmentsMarkdown(
|
|
182
|
+
modelId: ObjectID,
|
|
183
|
+
attachmentApiPath: string,
|
|
184
|
+
): Promise<string> {
|
|
185
|
+
if (!modelId) {
|
|
186
|
+
return "";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const noteWithAttachments: Model | null = await this.findOneById({
|
|
190
|
+
id: modelId,
|
|
191
|
+
select: {
|
|
192
|
+
attachments: {
|
|
193
|
+
_id: true,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
props: {
|
|
197
|
+
isRoot: true,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
if (!noteWithAttachments || !noteWithAttachments.attachments) {
|
|
202
|
+
return "";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const attachmentIds: Array<ObjectID> = noteWithAttachments.attachments
|
|
206
|
+
.map((file: File) => {
|
|
207
|
+
if (file.id) {
|
|
208
|
+
return file.id;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (file._id) {
|
|
212
|
+
return new ObjectID(file._id);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return null;
|
|
216
|
+
})
|
|
217
|
+
.filter((id: ObjectID | null): id is ObjectID => {
|
|
218
|
+
return Boolean(id);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
if (!attachmentIds.length) {
|
|
222
|
+
return "";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return await FileAttachmentMarkdownUtil.buildAttachmentMarkdown({
|
|
226
|
+
modelId,
|
|
227
|
+
attachmentIds,
|
|
228
|
+
attachmentApiPath,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
69
231
|
}
|
|
70
232
|
|
|
71
233
|
export default new Service();
|
|
@@ -139,6 +139,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
139
139
|
displayColor: Yellow500,
|
|
140
140
|
feedInfoInMarkdown: `**Alert ${alert?.alertNumberWithPrefix || "#" + (alert?.alertNumber || "N/A")}** added to episode: ${alert?.title || "No title"}`,
|
|
141
141
|
userId: createdItem.addedByUserId || undefined,
|
|
142
|
+
workspaceNotification: {
|
|
143
|
+
sendWorkspaceNotification: true,
|
|
144
|
+
notifyUserId: createdItem.addedByUserId || undefined,
|
|
145
|
+
},
|
|
142
146
|
});
|
|
143
147
|
|
|
144
148
|
// Create feed item on alert
|
|
@@ -235,6 +239,9 @@ export class Service extends DatabaseService<Model> {
|
|
|
235
239
|
alertEpisodeFeedEventType: AlertEpisodeFeedEventType.AlertRemoved,
|
|
236
240
|
displayColor: Green500,
|
|
237
241
|
feedInfoInMarkdown: `**Alert #${alert?.alertNumber || "N/A"}** removed from episode: ${alert?.title || "No title"}`,
|
|
242
|
+
workspaceNotification: {
|
|
243
|
+
sendWorkspaceNotification: true,
|
|
244
|
+
},
|
|
238
245
|
});
|
|
239
246
|
|
|
240
247
|
// Create feed item on alert
|
|
@@ -1,10 +1,196 @@
|
|
|
1
|
+
import ObjectID from "../../Types/ObjectID";
|
|
2
|
+
import { OnCreate, OnDelete } from "../Types/Database/Hooks";
|
|
1
3
|
import DatabaseService from "./DatabaseService";
|
|
2
4
|
import Model from "../../Models/DatabaseModels/AlertEpisodeOwnerTeam";
|
|
5
|
+
import AlertEpisodeFeedService from "./AlertEpisodeFeedService";
|
|
6
|
+
import { AlertEpisodeFeedEventType } from "../../Models/DatabaseModels/AlertEpisodeFeed";
|
|
7
|
+
import { Gray500, Red500 } from "../../Types/BrandColors";
|
|
8
|
+
import TeamService from "./TeamService";
|
|
9
|
+
import Team from "../../Models/DatabaseModels/Team";
|
|
10
|
+
import DeleteBy from "../Types/Database/DeleteBy";
|
|
11
|
+
import AlertEpisodeService from "./AlertEpisodeService";
|
|
12
|
+
import AlertEpisode from "../../Models/DatabaseModels/AlertEpisode";
|
|
13
|
+
import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
|
|
14
|
+
import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
|
|
15
|
+
import WorkspaceNotificationRule from "../../Models/DatabaseModels/WorkspaceNotificationRule";
|
|
16
|
+
import logger from "../Utils/Logger";
|
|
17
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
3
18
|
|
|
4
19
|
export class Service extends DatabaseService<Model> {
|
|
5
20
|
public constructor() {
|
|
6
21
|
super(Model);
|
|
7
22
|
}
|
|
23
|
+
|
|
24
|
+
@CaptureSpan()
|
|
25
|
+
protected override async onBeforeDelete(
|
|
26
|
+
deleteBy: DeleteBy<Model>,
|
|
27
|
+
): Promise<OnDelete<Model>> {
|
|
28
|
+
const itemsToDelete: Model[] = await this.findBy({
|
|
29
|
+
query: deleteBy.query,
|
|
30
|
+
limit: deleteBy.limit,
|
|
31
|
+
skip: deleteBy.skip,
|
|
32
|
+
props: {
|
|
33
|
+
isRoot: true,
|
|
34
|
+
},
|
|
35
|
+
select: {
|
|
36
|
+
alertEpisodeId: true,
|
|
37
|
+
projectId: true,
|
|
38
|
+
teamId: true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
carryForward: {
|
|
44
|
+
itemsToDelete: itemsToDelete,
|
|
45
|
+
},
|
|
46
|
+
deleteBy: deleteBy,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@CaptureSpan()
|
|
51
|
+
protected override async onDeleteSuccess(
|
|
52
|
+
onDelete: OnDelete<Model>,
|
|
53
|
+
_itemIdsBeforeDelete: Array<ObjectID>,
|
|
54
|
+
): Promise<OnDelete<Model>> {
|
|
55
|
+
const deleteByUserId: ObjectID | undefined =
|
|
56
|
+
onDelete.deleteBy.deletedByUser?.id || onDelete.deleteBy.props.userId;
|
|
57
|
+
|
|
58
|
+
const itemsToDelete: Model[] = onDelete.carryForward.itemsToDelete;
|
|
59
|
+
|
|
60
|
+
for (const item of itemsToDelete) {
|
|
61
|
+
const alertEpisodeId: ObjectID | undefined = item.alertEpisodeId;
|
|
62
|
+
const projectId: ObjectID | undefined = item.projectId;
|
|
63
|
+
const teamId: ObjectID | undefined = item.teamId;
|
|
64
|
+
|
|
65
|
+
if (alertEpisodeId && teamId && projectId) {
|
|
66
|
+
const team: Team | null = await TeamService.findOneById({
|
|
67
|
+
id: teamId,
|
|
68
|
+
select: {
|
|
69
|
+
name: true,
|
|
70
|
+
},
|
|
71
|
+
props: {
|
|
72
|
+
isRoot: true,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const episodeNumberResult: {
|
|
77
|
+
number: number | null;
|
|
78
|
+
numberWithPrefix: string | null;
|
|
79
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
80
|
+
episodeId: alertEpisodeId,
|
|
81
|
+
});
|
|
82
|
+
const episodeNumberDisplay: string =
|
|
83
|
+
episodeNumberResult.numberWithPrefix ||
|
|
84
|
+
"#" + episodeNumberResult.number;
|
|
85
|
+
|
|
86
|
+
if (team && team.name) {
|
|
87
|
+
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
88
|
+
alertEpisodeId: alertEpisodeId,
|
|
89
|
+
projectId: projectId,
|
|
90
|
+
alertEpisodeFeedEventType:
|
|
91
|
+
AlertEpisodeFeedEventType.OwnerTeamRemoved,
|
|
92
|
+
displayColor: Red500,
|
|
93
|
+
feedInfoInMarkdown: `👨🏻👩🏻👦🏻 Removed team **${team.name}** from the [Episode ${episodeNumberDisplay}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(projectId!, alertEpisodeId!)).toString()}) as the owner.`,
|
|
94
|
+
userId: deleteByUserId || undefined,
|
|
95
|
+
workspaceNotification: {
|
|
96
|
+
sendWorkspaceNotification: true,
|
|
97
|
+
notifyUserId: deleteByUserId || undefined,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return onDelete;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@CaptureSpan()
|
|
108
|
+
public override async onCreateSuccess(
|
|
109
|
+
onCreate: OnCreate<Model>,
|
|
110
|
+
createdItem: Model,
|
|
111
|
+
): Promise<Model> {
|
|
112
|
+
const alertEpisodeId: ObjectID | undefined = createdItem.alertEpisodeId;
|
|
113
|
+
const projectId: ObjectID | undefined = createdItem.projectId;
|
|
114
|
+
const teamId: ObjectID | undefined = createdItem.teamId;
|
|
115
|
+
const createdByUserId: ObjectID | undefined =
|
|
116
|
+
createdItem.createdByUserId || onCreate.createBy.props.userId;
|
|
117
|
+
|
|
118
|
+
if (alertEpisodeId && teamId && projectId) {
|
|
119
|
+
const team: Team | null = await TeamService.findOneById({
|
|
120
|
+
id: teamId,
|
|
121
|
+
select: {
|
|
122
|
+
name: true,
|
|
123
|
+
},
|
|
124
|
+
props: {
|
|
125
|
+
isRoot: true,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if (team && team.name) {
|
|
130
|
+
const episodeNumberResult: {
|
|
131
|
+
number: number | null;
|
|
132
|
+
numberWithPrefix: string | null;
|
|
133
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
134
|
+
episodeId: alertEpisodeId,
|
|
135
|
+
});
|
|
136
|
+
const episodeNumberDisplay: string =
|
|
137
|
+
episodeNumberResult.numberWithPrefix ||
|
|
138
|
+
"#" + episodeNumberResult.number;
|
|
139
|
+
|
|
140
|
+
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
141
|
+
alertEpisodeId: alertEpisodeId,
|
|
142
|
+
projectId: projectId,
|
|
143
|
+
alertEpisodeFeedEventType: AlertEpisodeFeedEventType.OwnerTeamAdded,
|
|
144
|
+
displayColor: Gray500,
|
|
145
|
+
feedInfoInMarkdown: `👨🏻👩🏻👦🏻 Added team **${team.name}** to the [Episode ${episodeNumberDisplay}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(projectId!, alertEpisodeId!)).toString()}) as the owner.`,
|
|
146
|
+
userId: createdByUserId || undefined,
|
|
147
|
+
workspaceNotification: {
|
|
148
|
+
sendWorkspaceNotification: true,
|
|
149
|
+
notifyUserId: createdByUserId || undefined,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// get notification rule where inviteOwners is true.
|
|
155
|
+
const notificationRules: Array<WorkspaceNotificationRule> =
|
|
156
|
+
await WorkspaceNotificationRuleService.getNotificationRulesWhereInviteOwnersIsTrue(
|
|
157
|
+
{
|
|
158
|
+
projectId: projectId,
|
|
159
|
+
notificationFor: {
|
|
160
|
+
alertEpisodeId: alertEpisodeId,
|
|
161
|
+
},
|
|
162
|
+
notificationRuleEventType: NotificationRuleEventType.AlertEpisode,
|
|
163
|
+
},
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Fetch episode to get workspace channels
|
|
167
|
+
const episode: AlertEpisode | null =
|
|
168
|
+
await AlertEpisodeService.findOneById({
|
|
169
|
+
id: alertEpisodeId,
|
|
170
|
+
select: {
|
|
171
|
+
postUpdatesToWorkspaceChannels: true,
|
|
172
|
+
},
|
|
173
|
+
props: {
|
|
174
|
+
isRoot: true,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (episode) {
|
|
179
|
+
WorkspaceNotificationRuleService.inviteTeamsBasedOnRulesAndWorkspaceChannels(
|
|
180
|
+
{
|
|
181
|
+
notificationRules: notificationRules,
|
|
182
|
+
projectId: projectId,
|
|
183
|
+
workspaceChannels: episode.postUpdatesToWorkspaceChannels || [],
|
|
184
|
+
teamIds: [teamId],
|
|
185
|
+
},
|
|
186
|
+
).catch((error: Error) => {
|
|
187
|
+
logger.error(error);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return createdItem;
|
|
193
|
+
}
|
|
8
194
|
}
|
|
9
195
|
|
|
10
196
|
export default new Service();
|
|
@@ -1,10 +1,190 @@
|
|
|
1
|
+
import ObjectID from "../../Types/ObjectID";
|
|
1
2
|
import DatabaseService from "./DatabaseService";
|
|
2
3
|
import Model from "../../Models/DatabaseModels/AlertEpisodeOwnerUser";
|
|
4
|
+
import AlertEpisodeFeedService from "./AlertEpisodeFeedService";
|
|
5
|
+
import { AlertEpisodeFeedEventType } from "../../Models/DatabaseModels/AlertEpisodeFeed";
|
|
6
|
+
import { Gray500, Red500 } from "../../Types/BrandColors";
|
|
7
|
+
import User from "../../Models/DatabaseModels/User";
|
|
8
|
+
import UserService from "./UserService";
|
|
9
|
+
import { OnCreate, OnDelete } from "../Types/Database/Hooks";
|
|
10
|
+
import DeleteBy from "../Types/Database/DeleteBy";
|
|
11
|
+
import AlertEpisodeService from "./AlertEpisodeService";
|
|
12
|
+
import AlertEpisode from "../../Models/DatabaseModels/AlertEpisode";
|
|
13
|
+
import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
|
|
14
|
+
import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
|
|
15
|
+
import WorkspaceNotificationRule from "../../Models/DatabaseModels/WorkspaceNotificationRule";
|
|
16
|
+
import logger from "../Utils/Logger";
|
|
17
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
3
18
|
|
|
4
19
|
export class Service extends DatabaseService<Model> {
|
|
5
20
|
public constructor() {
|
|
6
21
|
super(Model);
|
|
7
22
|
}
|
|
23
|
+
|
|
24
|
+
@CaptureSpan()
|
|
25
|
+
protected override async onBeforeDelete(
|
|
26
|
+
deleteBy: DeleteBy<Model>,
|
|
27
|
+
): Promise<OnDelete<Model>> {
|
|
28
|
+
const itemsToDelete: Model[] = await this.findBy({
|
|
29
|
+
query: deleteBy.query,
|
|
30
|
+
limit: deleteBy.limit,
|
|
31
|
+
skip: deleteBy.skip,
|
|
32
|
+
props: {
|
|
33
|
+
isRoot: true,
|
|
34
|
+
},
|
|
35
|
+
select: {
|
|
36
|
+
alertEpisodeId: true,
|
|
37
|
+
projectId: true,
|
|
38
|
+
userId: true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
carryForward: {
|
|
44
|
+
itemsToDelete: itemsToDelete,
|
|
45
|
+
},
|
|
46
|
+
deleteBy: deleteBy,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@CaptureSpan()
|
|
51
|
+
protected override async onDeleteSuccess(
|
|
52
|
+
onDelete: OnDelete<Model>,
|
|
53
|
+
_itemIdsBeforeDelete: Array<ObjectID>,
|
|
54
|
+
): Promise<OnDelete<Model>> {
|
|
55
|
+
const deleteByUserId: ObjectID | undefined =
|
|
56
|
+
onDelete.deleteBy.deletedByUser?.id || onDelete.deleteBy.props.userId;
|
|
57
|
+
|
|
58
|
+
const itemsToDelete: Model[] = onDelete.carryForward.itemsToDelete;
|
|
59
|
+
|
|
60
|
+
for (const item of itemsToDelete) {
|
|
61
|
+
const alertEpisodeId: ObjectID | undefined = item.alertEpisodeId;
|
|
62
|
+
const projectId: ObjectID | undefined = item.projectId;
|
|
63
|
+
const userId: ObjectID | undefined = item.userId;
|
|
64
|
+
|
|
65
|
+
if (alertEpisodeId && userId && projectId) {
|
|
66
|
+
const user: User | null = await UserService.findOneById({
|
|
67
|
+
id: userId,
|
|
68
|
+
select: {
|
|
69
|
+
name: true,
|
|
70
|
+
email: true,
|
|
71
|
+
},
|
|
72
|
+
props: {
|
|
73
|
+
isRoot: true,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const episodeNumberResult: {
|
|
78
|
+
number: number | null;
|
|
79
|
+
numberWithPrefix: string | null;
|
|
80
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
81
|
+
episodeId: alertEpisodeId,
|
|
82
|
+
});
|
|
83
|
+
const episodeNumberDisplay: string =
|
|
84
|
+
episodeNumberResult.numberWithPrefix ||
|
|
85
|
+
"#" + episodeNumberResult.number;
|
|
86
|
+
|
|
87
|
+
if (user && user.name) {
|
|
88
|
+
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
89
|
+
alertEpisodeId: alertEpisodeId,
|
|
90
|
+
projectId: projectId,
|
|
91
|
+
alertEpisodeFeedEventType:
|
|
92
|
+
AlertEpisodeFeedEventType.OwnerUserRemoved,
|
|
93
|
+
displayColor: Red500,
|
|
94
|
+
feedInfoInMarkdown: `👨🏻💻 Removed **${user.name.toString()}** (${user.email?.toString()}) from the [Episode ${episodeNumberDisplay}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(projectId!, alertEpisodeId!)).toString()}) as the owner.`,
|
|
95
|
+
userId: deleteByUserId || undefined,
|
|
96
|
+
workspaceNotification: {
|
|
97
|
+
sendWorkspaceNotification: true,
|
|
98
|
+
notifyUserId: userId || undefined,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return onDelete;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@CaptureSpan()
|
|
109
|
+
public override async onCreateSuccess(
|
|
110
|
+
onCreate: OnCreate<Model>,
|
|
111
|
+
createdItem: Model,
|
|
112
|
+
): Promise<Model> {
|
|
113
|
+
const alertEpisodeId: ObjectID | undefined = createdItem.alertEpisodeId;
|
|
114
|
+
const projectId: ObjectID | undefined = createdItem.projectId;
|
|
115
|
+
const userId: ObjectID | undefined = createdItem.userId;
|
|
116
|
+
const createdByUserId: ObjectID | undefined =
|
|
117
|
+
createdItem.createdByUserId || onCreate.createBy.props.userId;
|
|
118
|
+
|
|
119
|
+
if (alertEpisodeId && userId && projectId) {
|
|
120
|
+
const episodeNumberResult: {
|
|
121
|
+
number: number | null;
|
|
122
|
+
numberWithPrefix: string | null;
|
|
123
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
124
|
+
episodeId: alertEpisodeId,
|
|
125
|
+
});
|
|
126
|
+
const episodeNumberDisplay: string =
|
|
127
|
+
episodeNumberResult.numberWithPrefix ||
|
|
128
|
+
"#" + episodeNumberResult.number;
|
|
129
|
+
|
|
130
|
+
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
131
|
+
alertEpisodeId: alertEpisodeId,
|
|
132
|
+
projectId: projectId,
|
|
133
|
+
alertEpisodeFeedEventType: AlertEpisodeFeedEventType.OwnerUserAdded,
|
|
134
|
+
displayColor: Gray500,
|
|
135
|
+
feedInfoInMarkdown: `👨🏻💻 Added **${await UserService.getUserMarkdownString(
|
|
136
|
+
{
|
|
137
|
+
userId: userId,
|
|
138
|
+
projectId: projectId,
|
|
139
|
+
},
|
|
140
|
+
)}** to the [Episode ${episodeNumberDisplay}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(projectId!, alertEpisodeId!)).toString()}) as the owner.`,
|
|
141
|
+
userId: createdByUserId || undefined,
|
|
142
|
+
workspaceNotification: {
|
|
143
|
+
sendWorkspaceNotification: true,
|
|
144
|
+
notifyUserId: userId || undefined,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// get notification rule where inviteOwners is true.
|
|
149
|
+
const notificationRules: Array<WorkspaceNotificationRule> =
|
|
150
|
+
await WorkspaceNotificationRuleService.getNotificationRulesWhereInviteOwnersIsTrue(
|
|
151
|
+
{
|
|
152
|
+
projectId: projectId,
|
|
153
|
+
notificationFor: {
|
|
154
|
+
alertEpisodeId: alertEpisodeId,
|
|
155
|
+
},
|
|
156
|
+
notificationRuleEventType: NotificationRuleEventType.AlertEpisode,
|
|
157
|
+
},
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
// Fetch episode to get workspace channels
|
|
161
|
+
const episode: AlertEpisode | null =
|
|
162
|
+
await AlertEpisodeService.findOneById({
|
|
163
|
+
id: alertEpisodeId,
|
|
164
|
+
select: {
|
|
165
|
+
postUpdatesToWorkspaceChannels: true,
|
|
166
|
+
},
|
|
167
|
+
props: {
|
|
168
|
+
isRoot: true,
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
if (episode) {
|
|
173
|
+
WorkspaceNotificationRuleService.inviteUsersBasedOnRulesAndWorkspaceChannels(
|
|
174
|
+
{
|
|
175
|
+
notificationRules: notificationRules,
|
|
176
|
+
projectId: projectId,
|
|
177
|
+
workspaceChannels: episode.postUpdatesToWorkspaceChannels || [],
|
|
178
|
+
userIds: [userId],
|
|
179
|
+
},
|
|
180
|
+
).catch((error: Error) => {
|
|
181
|
+
logger.error(error);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return createdItem;
|
|
187
|
+
}
|
|
8
188
|
}
|
|
9
189
|
|
|
10
190
|
export default new Service();
|
|
@@ -38,6 +38,8 @@ import User from "../../Models/DatabaseModels/User";
|
|
|
38
38
|
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
39
39
|
import NotificationRuleWorkspaceChannel from "../../Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel";
|
|
40
40
|
import WorkspaceType from "../../Types/Workspace/WorkspaceType";
|
|
41
|
+
import AlertEpisodeWorkspaceMessages from "../Utils/Workspace/WorkspaceMessages/AlertEpisode";
|
|
42
|
+
import { MessageBlocksByWorkspaceType } from "./WorkspaceNotificationRuleService";
|
|
41
43
|
import Typeof from "../../Types/Typeof";
|
|
42
44
|
import AlertService from "./AlertService";
|
|
43
45
|
import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
|
|
@@ -124,6 +126,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
124
126
|
|
|
125
127
|
// Create initial state timeline entry
|
|
126
128
|
Promise.resolve()
|
|
129
|
+
.then(async () => {
|
|
130
|
+
try {
|
|
131
|
+
if (createdItem.projectId && createdItem.id) {
|
|
132
|
+
await this.handleEpisodeWorkspaceOperationsAsync(createdItem);
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
logger.error(
|
|
136
|
+
`Workspace operations failed in AlertEpisodeService.onCreateSuccess: ${error}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
})
|
|
127
140
|
.then(async () => {
|
|
128
141
|
try {
|
|
129
142
|
await this.changeEpisodeState({
|
|
@@ -170,6 +183,51 @@ export class Service extends DatabaseService<Model> {
|
|
|
170
183
|
return createdItem;
|
|
171
184
|
}
|
|
172
185
|
|
|
186
|
+
@CaptureSpan()
|
|
187
|
+
private async handleEpisodeWorkspaceOperationsAsync(
|
|
188
|
+
createdItem: Model,
|
|
189
|
+
): Promise<void> {
|
|
190
|
+
try {
|
|
191
|
+
if (!createdItem.projectId || !createdItem.id) {
|
|
192
|
+
throw new BadDataException(
|
|
193
|
+
"projectId and id are required for workspace operations",
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const workspaceResult: {
|
|
198
|
+
channelsCreated: Array<NotificationRuleWorkspaceChannel>;
|
|
199
|
+
} | null =
|
|
200
|
+
await AlertEpisodeWorkspaceMessages.createChannelsAndInviteUsersToChannels(
|
|
201
|
+
{
|
|
202
|
+
projectId: createdItem.projectId,
|
|
203
|
+
alertEpisodeId: createdItem.id,
|
|
204
|
+
episodeNumber: createdItem.episodeNumber || 0,
|
|
205
|
+
...(createdItem.episodeNumberWithPrefix
|
|
206
|
+
? {
|
|
207
|
+
episodeNumberWithPrefix: createdItem.episodeNumberWithPrefix,
|
|
208
|
+
}
|
|
209
|
+
: {}),
|
|
210
|
+
},
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
if (workspaceResult && workspaceResult.channelsCreated?.length > 0) {
|
|
214
|
+
await this.updateOneById({
|
|
215
|
+
id: createdItem.id,
|
|
216
|
+
data: {
|
|
217
|
+
postUpdatesToWorkspaceChannels:
|
|
218
|
+
workspaceResult.channelsCreated || [],
|
|
219
|
+
},
|
|
220
|
+
props: {
|
|
221
|
+
isRoot: true,
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
logger.error(`Error in handleEpisodeWorkspaceOperationsAsync: ${error}`);
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
173
231
|
@CaptureSpan()
|
|
174
232
|
private async createEpisodeCreatedFeed(episode: Model): Promise<void> {
|
|
175
233
|
if (!episode.id || !episode.projectId) {
|
|
@@ -190,6 +248,12 @@ export class Service extends DatabaseService<Model> {
|
|
|
190
248
|
feedInfoInMarkdown += `This episode was manually created.\n\n`;
|
|
191
249
|
}
|
|
192
250
|
|
|
251
|
+
const episodeCreateMessageBlocks: Array<MessageBlocksByWorkspaceType> =
|
|
252
|
+
await AlertEpisodeWorkspaceMessages.getAlertEpisodeCreateMessageBlocks({
|
|
253
|
+
alertEpisodeId: episode.id,
|
|
254
|
+
projectId: episode.projectId,
|
|
255
|
+
});
|
|
256
|
+
|
|
193
257
|
await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
|
|
194
258
|
alertEpisodeId: episode.id,
|
|
195
259
|
projectId: episode.projectId,
|
|
@@ -197,6 +261,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
197
261
|
displayColor: Red500,
|
|
198
262
|
feedInfoInMarkdown: feedInfoInMarkdown,
|
|
199
263
|
userId: episode.createdByUserId || undefined,
|
|
264
|
+
workspaceNotification: {
|
|
265
|
+
appendMessageBlocks: episodeCreateMessageBlocks,
|
|
266
|
+
sendWorkspaceNotification: true,
|
|
267
|
+
},
|
|
200
268
|
});
|
|
201
269
|
}
|
|
202
270
|
|
|
@@ -374,6 +374,11 @@ export class Service extends DatabaseService<AlertEpisodeStateTimeline> {
|
|
|
374
374
|
? `**Cause:** \n${createdItem.rootCause}`
|
|
375
375
|
: undefined,
|
|
376
376
|
userId: createdItem.createdByUserId || onCreate.createBy.props.userId,
|
|
377
|
+
workspaceNotification: {
|
|
378
|
+
sendWorkspaceNotification: true,
|
|
379
|
+
notifyUserId:
|
|
380
|
+
createdItem.createdByUserId || onCreate.createBy.props.userId,
|
|
381
|
+
},
|
|
377
382
|
});
|
|
378
383
|
|
|
379
384
|
return createdItem;
|