@oneuptime/common 7.0.3822 → 7.0.3826
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/Services/AlertStateTimelineService.ts +192 -86
- package/Server/Services/IncidentStateTimelineService.ts +205 -103
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +201 -101
- package/build/dist/Server/Services/AlertStateTimelineService.js +171 -72
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +171 -73
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +174 -80
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/package.json +2 -2
|
@@ -82,28 +82,65 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
82
82
|
if (userId) {
|
|
83
83
|
createBy.data.rootCause = `Alert state created by ${await UserService.getUserMarkdownString(
|
|
84
84
|
{
|
|
85
|
-
userId: userId
|
|
85
|
+
userId: userId!,
|
|
86
86
|
projectId: createBy.data.projectId || createBy.props.tenantId!,
|
|
87
87
|
},
|
|
88
88
|
)}`;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
92
|
+
const stateBeforeThis: AlertStateTimeline | null = await this.findOneBy({
|
|
93
|
+
query: {
|
|
94
|
+
alertId: createBy.data.alertId,
|
|
95
|
+
startsAt: QueryHelper.lessThanEqualTo(createBy.data.startsAt),
|
|
96
|
+
},
|
|
97
|
+
sort: {
|
|
98
|
+
startsAt: SortOrder.Descending,
|
|
99
|
+
},
|
|
100
|
+
props: {
|
|
101
|
+
isRoot: true,
|
|
102
|
+
},
|
|
103
|
+
select: {
|
|
104
|
+
alertStateId: true,
|
|
105
|
+
startsAt: true,
|
|
106
|
+
endsAt: true,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
logger.debug("State Before this");
|
|
111
|
+
logger.debug(stateBeforeThis);
|
|
112
|
+
|
|
113
|
+
// If this is the first state, then do not notify the owner.
|
|
114
|
+
if (!stateBeforeThis) {
|
|
115
|
+
// since this is the first status, do not notify the owner.
|
|
116
|
+
createBy.data.isOwnerNotified = true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const stateAfterThis: AlertStateTimeline | null = await this.findOneBy({
|
|
120
|
+
query: {
|
|
121
|
+
alertId: createBy.data.alertId,
|
|
122
|
+
startsAt: QueryHelper.greaterThan(createBy.data.startsAt),
|
|
123
|
+
},
|
|
124
|
+
sort: {
|
|
125
|
+
startsAt: SortOrder.Ascending,
|
|
126
|
+
},
|
|
127
|
+
props: {
|
|
128
|
+
isRoot: true,
|
|
129
|
+
},
|
|
130
|
+
select: {
|
|
131
|
+
alertStateId: true,
|
|
132
|
+
startsAt: true,
|
|
133
|
+
endsAt: true,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// compute ends at. It's the start of the next status.
|
|
138
|
+
if (stateAfterThis && stateAfterThis.startsAt) {
|
|
139
|
+
createBy.data.endsAt = stateAfterThis.startsAt;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
logger.debug("State After this");
|
|
143
|
+
logger.debug(stateAfterThis);
|
|
107
144
|
|
|
108
145
|
const internalNote: string | undefined = (
|
|
109
146
|
createBy.miscDataProps as JSONObject | undefined
|
|
@@ -129,7 +166,8 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
129
166
|
return {
|
|
130
167
|
createBy,
|
|
131
168
|
carryForward: {
|
|
132
|
-
|
|
169
|
+
statusTimelineBeforeThisStatus: stateBeforeThis || null,
|
|
170
|
+
statusTimelineAfterThisStatus: stateAfterThis || null,
|
|
133
171
|
privateNote: privateNote,
|
|
134
172
|
},
|
|
135
173
|
};
|
|
@@ -147,18 +185,69 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
147
185
|
throw new BadDataException("alertStateId is null");
|
|
148
186
|
}
|
|
149
187
|
|
|
150
|
-
|
|
188
|
+
logger.debug("Status Timeline Before this");
|
|
189
|
+
logger.debug(onCreate.carryForward.statusTimelineBeforeThisStatus);
|
|
190
|
+
|
|
191
|
+
logger.debug("Status Timeline After this");
|
|
192
|
+
logger.debug(onCreate.carryForward.statusTimelineAfterThisStatus);
|
|
151
193
|
|
|
152
|
-
|
|
194
|
+
logger.debug("Created Item");
|
|
195
|
+
logger.debug(createdItem);
|
|
196
|
+
|
|
197
|
+
// now there are three cases.
|
|
198
|
+
// 1. This is the first status OR there's no status after this.
|
|
199
|
+
if (!onCreate.carryForward.statusTimelineBeforeThisStatus) {
|
|
200
|
+
// This is the first status, no need to update previous status.
|
|
201
|
+
logger.debug("This is the first status.");
|
|
202
|
+
} else if (!onCreate.carryForward.statusTimelineAfterThisStatus) {
|
|
203
|
+
// 2. This is the last status.
|
|
204
|
+
// Update the previous status to end at the start of this status.
|
|
205
|
+
await this.updateOneById({
|
|
206
|
+
id: onCreate.carryForward.statusTimelineBeforeThisStatus.id!,
|
|
207
|
+
data: {
|
|
208
|
+
endsAt: createdItem.startsAt!,
|
|
209
|
+
},
|
|
210
|
+
props: {
|
|
211
|
+
isRoot: true,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
logger.debug("This is the last status.");
|
|
215
|
+
} else {
|
|
216
|
+
// 3. This is in the middle.
|
|
217
|
+
// Update the previous status to end at the start of this status.
|
|
153
218
|
await this.updateOneById({
|
|
154
|
-
id: onCreate.carryForward.
|
|
219
|
+
id: onCreate.carryForward.statusTimelineBeforeThisStatus.id!,
|
|
155
220
|
data: {
|
|
156
|
-
endsAt: createdItem.
|
|
221
|
+
endsAt: createdItem.startsAt!,
|
|
157
222
|
},
|
|
158
223
|
props: {
|
|
159
224
|
isRoot: true,
|
|
160
225
|
},
|
|
161
226
|
});
|
|
227
|
+
|
|
228
|
+
// Update the next status to start at the end of this status.
|
|
229
|
+
await this.updateOneById({
|
|
230
|
+
id: onCreate.carryForward.statusTimelineAfterThisStatus.id!,
|
|
231
|
+
data: {
|
|
232
|
+
startsAt: createdItem.endsAt!,
|
|
233
|
+
},
|
|
234
|
+
props: {
|
|
235
|
+
isRoot: true,
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
logger.debug("This status is in the middle.");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (!createdItem.endsAt) {
|
|
242
|
+
await AlertService.updateOneBy({
|
|
243
|
+
query: {
|
|
244
|
+
_id: createdItem.alertId?.toString(),
|
|
245
|
+
},
|
|
246
|
+
data: {
|
|
247
|
+
currentAlertStateId: createdItem.alertStateId,
|
|
248
|
+
},
|
|
249
|
+
props: onCreate.createBy.props,
|
|
250
|
+
});
|
|
162
251
|
}
|
|
163
252
|
|
|
164
253
|
const alertState: AlertState | null = await AlertStateService.findOneBy({
|
|
@@ -210,7 +299,7 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
210
299
|
stateName +
|
|
211
300
|
"**",
|
|
212
301
|
moreInformationInMarkdown: `**Cause:**
|
|
213
|
-
|
|
302
|
+
${createdItem.rootCause}`,
|
|
214
303
|
userId: createdItem.createdByUserId || onCreate.createBy.props.userId,
|
|
215
304
|
workspaceNotification: {
|
|
216
305
|
sendWorkspaceNotification: true,
|
|
@@ -219,16 +308,6 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
219
308
|
},
|
|
220
309
|
});
|
|
221
310
|
|
|
222
|
-
await AlertService.updateOneBy({
|
|
223
|
-
query: {
|
|
224
|
-
_id: createdItem.alertId?.toString(),
|
|
225
|
-
},
|
|
226
|
-
data: {
|
|
227
|
-
currentAlertStateId: createdItem.alertStateId,
|
|
228
|
-
},
|
|
229
|
-
props: onCreate.createBy.props,
|
|
230
|
-
});
|
|
231
|
-
|
|
232
311
|
if (onCreate.carryForward.privateNote) {
|
|
233
312
|
const privateNote: string = onCreate.carryForward.privateNote;
|
|
234
313
|
|
|
@@ -266,6 +345,7 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
266
345
|
select: {
|
|
267
346
|
alertId: true,
|
|
268
347
|
startsAt: true,
|
|
348
|
+
endsAt: true,
|
|
269
349
|
},
|
|
270
350
|
props: {
|
|
271
351
|
isRoot: true,
|
|
@@ -285,78 +365,104 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
285
365
|
},
|
|
286
366
|
});
|
|
287
367
|
|
|
368
|
+
if (!alertStateTimelineToBeDeleted) {
|
|
369
|
+
throw new BadDataException("Alert state timeline not found.");
|
|
370
|
+
}
|
|
371
|
+
|
|
288
372
|
if (alertStateTimeline.isOne()) {
|
|
289
373
|
throw new BadDataException(
|
|
290
374
|
"Cannot delete the only state timeline. Alert should have at least one state in its timeline.",
|
|
291
375
|
);
|
|
292
376
|
}
|
|
293
377
|
|
|
294
|
-
|
|
295
|
-
|
|
378
|
+
// There are three cases.
|
|
379
|
+
// 1. This is the first state.
|
|
380
|
+
// 2. This is the last state.
|
|
381
|
+
// 3. This is in the middle.
|
|
382
|
+
|
|
383
|
+
const stateBeforeThis: AlertStateTimeline | null = await this.findOneBy(
|
|
384
|
+
{
|
|
296
385
|
query: {
|
|
386
|
+
_id: QueryHelper.notEquals(deleteBy.query._id as string),
|
|
297
387
|
alertId: alertId,
|
|
298
|
-
startsAt: QueryHelper.
|
|
299
|
-
alertStateTimelineToBeDeleted
|
|
388
|
+
startsAt: QueryHelper.lessThanEqualTo(
|
|
389
|
+
alertStateTimelineToBeDeleted.startsAt!,
|
|
300
390
|
),
|
|
301
391
|
},
|
|
302
392
|
sort: {
|
|
303
|
-
|
|
393
|
+
startsAt: SortOrder.Descending,
|
|
304
394
|
},
|
|
305
395
|
props: {
|
|
306
396
|
isRoot: true,
|
|
307
397
|
},
|
|
308
398
|
select: {
|
|
309
|
-
|
|
399
|
+
alertStateId: true,
|
|
310
400
|
startsAt: true,
|
|
401
|
+
endsAt: true,
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
const stateAfterThis: AlertStateTimeline | null = await this.findOneBy({
|
|
407
|
+
query: {
|
|
408
|
+
alertId: alertId,
|
|
409
|
+
startsAt: QueryHelper.greaterThan(
|
|
410
|
+
alertStateTimelineToBeDeleted.startsAt!,
|
|
411
|
+
),
|
|
412
|
+
},
|
|
413
|
+
sort: {
|
|
414
|
+
startsAt: SortOrder.Ascending,
|
|
415
|
+
},
|
|
416
|
+
props: {
|
|
417
|
+
isRoot: true,
|
|
418
|
+
},
|
|
419
|
+
select: {
|
|
420
|
+
alertStateId: true,
|
|
421
|
+
startsAt: true,
|
|
422
|
+
endsAt: true,
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
if (!stateBeforeThis) {
|
|
427
|
+
// This is the first state, no need to update previous state.
|
|
428
|
+
logger.debug("This is the first state.");
|
|
429
|
+
} else if (!stateAfterThis) {
|
|
430
|
+
// This is the last state.
|
|
431
|
+
// Update the previous state to end at the end of this state.
|
|
432
|
+
await this.updateOneById({
|
|
433
|
+
id: stateBeforeThis.id!,
|
|
434
|
+
data: {
|
|
435
|
+
endsAt: alertStateTimelineToBeDeleted.endsAt!,
|
|
436
|
+
},
|
|
437
|
+
props: {
|
|
438
|
+
isRoot: true,
|
|
439
|
+
},
|
|
440
|
+
});
|
|
441
|
+
logger.debug("This is the last state.");
|
|
442
|
+
} else {
|
|
443
|
+
// This state is in the middle.
|
|
444
|
+
// Update the previous state to end at the start of the next state.
|
|
445
|
+
await this.updateOneById({
|
|
446
|
+
id: stateBeforeThis.id!,
|
|
447
|
+
data: {
|
|
448
|
+
endsAt: stateAfterThis.startsAt!,
|
|
449
|
+
},
|
|
450
|
+
props: {
|
|
451
|
+
isRoot: true,
|
|
311
452
|
},
|
|
312
453
|
});
|
|
313
454
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
props: {
|
|
326
|
-
isRoot: true,
|
|
327
|
-
},
|
|
328
|
-
select: {
|
|
329
|
-
_id: true,
|
|
330
|
-
startsAt: true,
|
|
331
|
-
},
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
if (!afterState) {
|
|
335
|
-
// if there's nothing after then end date of before state is null.
|
|
336
|
-
|
|
337
|
-
await this.updateOneById({
|
|
338
|
-
id: beforeState.id!,
|
|
339
|
-
data: {
|
|
340
|
-
endsAt: null as any,
|
|
341
|
-
},
|
|
342
|
-
props: {
|
|
343
|
-
isRoot: true,
|
|
344
|
-
},
|
|
345
|
-
});
|
|
346
|
-
} else {
|
|
347
|
-
// if there's something after then end date of before state is start date of after state.
|
|
348
|
-
|
|
349
|
-
await this.updateOneById({
|
|
350
|
-
id: beforeState.id!,
|
|
351
|
-
data: {
|
|
352
|
-
endsAt: afterState.startsAt!,
|
|
353
|
-
},
|
|
354
|
-
props: {
|
|
355
|
-
isRoot: true,
|
|
356
|
-
},
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
}
|
|
455
|
+
// Update the next state to start at the start of this state.
|
|
456
|
+
await this.updateOneById({
|
|
457
|
+
id: stateAfterThis.id!,
|
|
458
|
+
data: {
|
|
459
|
+
startsAt: alertStateTimelineToBeDeleted.startsAt!,
|
|
460
|
+
},
|
|
461
|
+
props: {
|
|
462
|
+
isRoot: true,
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
logger.debug("This state is in the middle.");
|
|
360
466
|
}
|
|
361
467
|
}
|
|
362
468
|
|
|
@@ -374,14 +480,14 @@ export class Service extends DatabaseService<AlertStateTimeline> {
|
|
|
374
480
|
// this is alertId.
|
|
375
481
|
const alertId: ObjectID = onDelete.carryForward as ObjectID;
|
|
376
482
|
|
|
377
|
-
// get last status of this
|
|
483
|
+
// get last status of this alert.
|
|
378
484
|
const alertStateTimeline: AlertStateTimeline | null =
|
|
379
485
|
await this.findOneBy({
|
|
380
486
|
query: {
|
|
381
487
|
alertId: alertId,
|
|
382
488
|
},
|
|
383
489
|
sort: {
|
|
384
|
-
|
|
490
|
+
startsAt: SortOrder.Descending,
|
|
385
491
|
},
|
|
386
492
|
props: {
|
|
387
493
|
isRoot: true,
|