@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
|
@@ -25,6 +25,7 @@ import ScheduledMaintenanceStateTimeline from "Common/Models/DatabaseModels/Sche
|
|
|
25
25
|
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
26
26
|
import ScheduledMaintenanceFeedService from "./ScheduledMaintenanceFeedService";
|
|
27
27
|
import { ScheduledMaintenanceFeedEventType } from "../../Models/DatabaseModels/ScheduledMaintenanceFeed";
|
|
28
|
+
import logger from "../Utils/Logger";
|
|
28
29
|
|
|
29
30
|
export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline> {
|
|
30
31
|
public constructor() {
|
|
@@ -45,22 +46,55 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
45
46
|
createBy.data.startsAt = OneUptimeDate.getCurrentDate();
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
const
|
|
49
|
+
const stateBeforeThis: ScheduledMaintenanceStateTimeline | null =
|
|
49
50
|
await this.findOneBy({
|
|
50
51
|
query: {
|
|
51
52
|
scheduledMaintenanceId: createBy.data.scheduledMaintenanceId,
|
|
53
|
+
startsAt: QueryHelper.lessThanEqualTo(createBy.data.startsAt),
|
|
52
54
|
},
|
|
53
55
|
sort: {
|
|
54
|
-
|
|
56
|
+
startsAt: SortOrder.Descending,
|
|
55
57
|
},
|
|
56
58
|
props: {
|
|
57
59
|
isRoot: true,
|
|
58
60
|
},
|
|
59
61
|
select: {
|
|
60
|
-
|
|
62
|
+
scheduledMaintenanceStateId: true,
|
|
63
|
+
startsAt: true,
|
|
64
|
+
endsAt: true,
|
|
61
65
|
},
|
|
62
66
|
});
|
|
63
67
|
|
|
68
|
+
// If this is the first state, then do not notify the owner.
|
|
69
|
+
if (!stateBeforeThis) {
|
|
70
|
+
// since this is the first status, do not notify the owner.
|
|
71
|
+
createBy.data.isOwnerNotified = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const stateAfterThis: ScheduledMaintenanceStateTimeline | null =
|
|
75
|
+
await this.findOneBy({
|
|
76
|
+
query: {
|
|
77
|
+
scheduledMaintenanceId: createBy.data.scheduledMaintenanceId,
|
|
78
|
+
startsAt: QueryHelper.greaterThan(createBy.data.startsAt),
|
|
79
|
+
},
|
|
80
|
+
sort: {
|
|
81
|
+
startsAt: SortOrder.Ascending,
|
|
82
|
+
},
|
|
83
|
+
props: {
|
|
84
|
+
isRoot: true,
|
|
85
|
+
},
|
|
86
|
+
select: {
|
|
87
|
+
scheduledMaintenanceStateId: true,
|
|
88
|
+
startsAt: true,
|
|
89
|
+
endsAt: true,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// compute ends at. It's the start of the next status.
|
|
94
|
+
if (stateAfterThis && stateAfterThis.startsAt) {
|
|
95
|
+
createBy.data.endsAt = stateAfterThis.startsAt;
|
|
96
|
+
}
|
|
97
|
+
|
|
64
98
|
const publicNote: string | undefined = (
|
|
65
99
|
createBy.miscDataProps as JSONObject | undefined
|
|
66
100
|
)?.["publicNote"] as string | undefined;
|
|
@@ -93,8 +127,9 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
93
127
|
return {
|
|
94
128
|
createBy,
|
|
95
129
|
carryForward: {
|
|
96
|
-
|
|
97
|
-
|
|
130
|
+
statusTimelineBeforeThisStatus: stateBeforeThis || null,
|
|
131
|
+
statusTimelineAfterThisStatus: stateAfterThis || null,
|
|
132
|
+
publicNote: publicNote,
|
|
98
133
|
},
|
|
99
134
|
};
|
|
100
135
|
}
|
|
@@ -113,30 +148,71 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
113
148
|
|
|
114
149
|
// update the last status as ended.
|
|
115
150
|
|
|
116
|
-
|
|
151
|
+
logger.debug("Status Timeline Before this");
|
|
152
|
+
logger.debug(onCreate.carryForward.statusTimelineBeforeThisStatus);
|
|
153
|
+
|
|
154
|
+
logger.debug("Status Timeline After this");
|
|
155
|
+
logger.debug(onCreate.carryForward.statusTimelineAfterThisStatus);
|
|
156
|
+
|
|
157
|
+
logger.debug("Created Item");
|
|
158
|
+
logger.debug(createdItem);
|
|
159
|
+
|
|
160
|
+
// now there are three cases.
|
|
161
|
+
// 1. This is the first status OR there's no status after this.
|
|
162
|
+
if (!onCreate.carryForward.statusTimelineBeforeThisStatus) {
|
|
163
|
+
// This is the first status, no need to update previous status.
|
|
164
|
+
logger.debug("This is the first status.");
|
|
165
|
+
} else if (!onCreate.carryForward.statusTimelineAfterThisStatus) {
|
|
166
|
+
// 2. This is the last status.
|
|
167
|
+
// Update the previous status to end at the start of this status.
|
|
168
|
+
await this.updateOneById({
|
|
169
|
+
id: onCreate.carryForward.statusTimelineBeforeThisStatus.id!,
|
|
170
|
+
data: {
|
|
171
|
+
endsAt: createdItem.startsAt!,
|
|
172
|
+
},
|
|
173
|
+
props: {
|
|
174
|
+
isRoot: true,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
logger.debug("This is the last status.");
|
|
178
|
+
} else {
|
|
179
|
+
// 3. This is in the middle.
|
|
180
|
+
// Update the previous status to end at the start of this status.
|
|
117
181
|
await this.updateOneById({
|
|
118
|
-
id: onCreate.carryForward.
|
|
182
|
+
id: onCreate.carryForward.statusTimelineBeforeThisStatus.id!,
|
|
119
183
|
data: {
|
|
120
|
-
endsAt: createdItem.
|
|
184
|
+
endsAt: createdItem.startsAt!,
|
|
121
185
|
},
|
|
122
186
|
props: {
|
|
123
187
|
isRoot: true,
|
|
124
188
|
},
|
|
125
189
|
});
|
|
190
|
+
|
|
191
|
+
// Update the next status to start at the end of this status.
|
|
192
|
+
await this.updateOneById({
|
|
193
|
+
id: onCreate.carryForward.statusTimelineAfterThisStatus.id!,
|
|
194
|
+
data: {
|
|
195
|
+
startsAt: createdItem.endsAt!,
|
|
196
|
+
},
|
|
197
|
+
props: {
|
|
198
|
+
isRoot: true,
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
logger.debug("This status is in the middle.");
|
|
126
202
|
}
|
|
127
203
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
}
|
|
204
|
+
if (!createdItem.endsAt) {
|
|
205
|
+
await ScheduledMaintenanceService.updateOneBy({
|
|
206
|
+
query: {
|
|
207
|
+
_id: createdItem.scheduledMaintenanceId?.toString(),
|
|
208
|
+
},
|
|
209
|
+
data: {
|
|
210
|
+
currentScheduledMaintenanceStateId:
|
|
211
|
+
createdItem.scheduledMaintenanceStateId,
|
|
212
|
+
},
|
|
213
|
+
props: onCreate.createBy.props,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
140
216
|
|
|
141
217
|
const scheduledMaintenanceState: ScheduledMaintenanceState | null =
|
|
142
218
|
await ScheduledMaintenanceStateService.findOneBy({
|
|
@@ -148,23 +224,18 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
148
224
|
},
|
|
149
225
|
select: {
|
|
150
226
|
_id: true,
|
|
151
|
-
color: true,
|
|
152
|
-
name: true,
|
|
153
227
|
isResolvedState: true,
|
|
154
228
|
isOngoingState: true,
|
|
155
229
|
isScheduledState: true,
|
|
230
|
+
color: true,
|
|
231
|
+
name: true,
|
|
156
232
|
},
|
|
157
233
|
});
|
|
158
234
|
|
|
159
235
|
const stateName: string = scheduledMaintenanceState?.name || "";
|
|
160
|
-
|
|
161
|
-
const scheduledMaintenanceNumber: number | null =
|
|
162
|
-
await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
|
|
163
|
-
scheduledMaintenanceId: createdItem.scheduledMaintenanceId,
|
|
164
|
-
});
|
|
236
|
+
let stateEmoji: string = "➡️";
|
|
165
237
|
|
|
166
238
|
// if resolved state then change emoji to ✅.
|
|
167
|
-
let stateEmoji: string = "➡️";
|
|
168
239
|
|
|
169
240
|
if (scheduledMaintenanceState?.isResolvedState) {
|
|
170
241
|
stateEmoji = "✅";
|
|
@@ -175,6 +246,11 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
175
246
|
stateEmoji = "🕒";
|
|
176
247
|
}
|
|
177
248
|
|
|
249
|
+
const scheduledMaintenanceNumber: number | null =
|
|
250
|
+
await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
|
|
251
|
+
scheduledMaintenanceId: createdItem.scheduledMaintenanceId,
|
|
252
|
+
});
|
|
253
|
+
|
|
178
254
|
const projectId: ObjectID = createdItem.projectId!;
|
|
179
255
|
const scheduledMaintenanceId: ObjectID =
|
|
180
256
|
createdItem.scheduledMaintenanceId!;
|
|
@@ -198,9 +274,6 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
198
274
|
},
|
|
199
275
|
});
|
|
200
276
|
|
|
201
|
-
// TODO: DELETE THIS WHEN WORKFLOW IS IMPLEMENMTED.
|
|
202
|
-
// check if this is resolved state, and if it is then resolve all the monitors.
|
|
203
|
-
|
|
204
277
|
const isResolvedState: ScheduledMaintenanceState | null =
|
|
205
278
|
await ScheduledMaintenanceStateService.findOneBy({
|
|
206
279
|
query: {
|
|
@@ -405,6 +478,7 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
405
478
|
select: {
|
|
406
479
|
scheduledMaintenanceId: true,
|
|
407
480
|
startsAt: true,
|
|
481
|
+
endsAt: true,
|
|
408
482
|
},
|
|
409
483
|
props: {
|
|
410
484
|
isRoot: true,
|
|
@@ -425,80 +499,106 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
425
499
|
},
|
|
426
500
|
});
|
|
427
501
|
|
|
502
|
+
if (!scheduledMaintenanceStateTimelineToBeDeleted) {
|
|
503
|
+
throw new BadDataException(
|
|
504
|
+
"Scheduled maintenance state timeline not found.",
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
|
|
428
508
|
if (scheduledMaintenanceStateTimeline.isOne()) {
|
|
429
509
|
throw new BadDataException(
|
|
430
510
|
"Cannot delete the only state timeline. Scheduled Maintenance should have at least one state in its timeline.",
|
|
431
511
|
);
|
|
432
512
|
}
|
|
433
513
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
514
|
+
// There are three cases.
|
|
515
|
+
// 1. This is the first state.
|
|
516
|
+
// 2. This is the last state.
|
|
517
|
+
// 3. This is in the middle.
|
|
518
|
+
|
|
519
|
+
const stateBeforeThis: ScheduledMaintenanceStateTimeline | null =
|
|
520
|
+
await this.findOneBy({
|
|
521
|
+
query: {
|
|
522
|
+
_id: QueryHelper.notEquals(deleteBy.query._id as string),
|
|
523
|
+
scheduledMaintenanceId: scheduledMaintenanceId,
|
|
524
|
+
startsAt: QueryHelper.lessThanEqualTo(
|
|
525
|
+
scheduledMaintenanceStateTimelineToBeDeleted.startsAt!,
|
|
526
|
+
),
|
|
527
|
+
},
|
|
528
|
+
sort: {
|
|
529
|
+
startsAt: SortOrder.Descending,
|
|
530
|
+
},
|
|
531
|
+
props: {
|
|
532
|
+
isRoot: true,
|
|
533
|
+
},
|
|
534
|
+
select: {
|
|
535
|
+
scheduledMaintenanceStateId: true,
|
|
536
|
+
startsAt: true,
|
|
537
|
+
endsAt: true,
|
|
538
|
+
},
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
const stateAfterThis: ScheduledMaintenanceStateTimeline | null =
|
|
542
|
+
await this.findOneBy({
|
|
543
|
+
query: {
|
|
544
|
+
scheduledMaintenanceId: scheduledMaintenanceId,
|
|
545
|
+
startsAt: QueryHelper.greaterThan(
|
|
546
|
+
scheduledMaintenanceStateTimelineToBeDeleted.startsAt!,
|
|
547
|
+
),
|
|
548
|
+
},
|
|
549
|
+
sort: {
|
|
550
|
+
startsAt: SortOrder.Ascending,
|
|
551
|
+
},
|
|
552
|
+
props: {
|
|
553
|
+
isRoot: true,
|
|
554
|
+
},
|
|
555
|
+
select: {
|
|
556
|
+
scheduledMaintenanceStateId: true,
|
|
557
|
+
startsAt: true,
|
|
558
|
+
endsAt: true,
|
|
559
|
+
},
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
if (!stateBeforeThis) {
|
|
563
|
+
// This is the first state, no need to update previous state.
|
|
564
|
+
logger.debug("This is the first state.");
|
|
565
|
+
} else if (!stateAfterThis) {
|
|
566
|
+
// This is the last state.
|
|
567
|
+
// Update the previous state to end at the end of this state.
|
|
568
|
+
await this.updateOneById({
|
|
569
|
+
id: stateBeforeThis.id!,
|
|
570
|
+
data: {
|
|
571
|
+
endsAt: scheduledMaintenanceStateTimelineToBeDeleted.endsAt!,
|
|
572
|
+
},
|
|
573
|
+
props: {
|
|
574
|
+
isRoot: true,
|
|
575
|
+
},
|
|
576
|
+
});
|
|
577
|
+
logger.debug("This is the last state.");
|
|
578
|
+
} else {
|
|
579
|
+
// This state is in the middle.
|
|
580
|
+
// Update the previous state to end at the start of the next state.
|
|
581
|
+
await this.updateOneById({
|
|
582
|
+
id: stateBeforeThis.id!,
|
|
583
|
+
data: {
|
|
584
|
+
endsAt: stateAfterThis.startsAt!,
|
|
585
|
+
},
|
|
586
|
+
props: {
|
|
587
|
+
isRoot: true,
|
|
588
|
+
},
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
// Update the next state to start at the start of this state.
|
|
592
|
+
await this.updateOneById({
|
|
593
|
+
id: stateAfterThis.id!,
|
|
594
|
+
data: {
|
|
595
|
+
startsAt: scheduledMaintenanceStateTimelineToBeDeleted.startsAt!,
|
|
596
|
+
},
|
|
597
|
+
props: {
|
|
598
|
+
isRoot: true,
|
|
599
|
+
},
|
|
600
|
+
});
|
|
601
|
+
logger.debug("This state is in the middle.");
|
|
502
602
|
}
|
|
503
603
|
}
|
|
504
604
|
|
|
@@ -517,14 +617,14 @@ export class Service extends DatabaseService<ScheduledMaintenanceStateTimeline>
|
|
|
517
617
|
const scheduledMaintenanceId: ObjectID =
|
|
518
618
|
onDelete.carryForward as ObjectID;
|
|
519
619
|
|
|
520
|
-
// get last status of this
|
|
620
|
+
// get last status of this scheduled maintenance.
|
|
521
621
|
const scheduledMaintenanceStateTimeline: ScheduledMaintenanceStateTimeline | null =
|
|
522
622
|
await this.findOneBy({
|
|
523
623
|
query: {
|
|
524
624
|
scheduledMaintenanceId: scheduledMaintenanceId,
|
|
525
625
|
},
|
|
526
626
|
sort: {
|
|
527
|
-
|
|
627
|
+
startsAt: SortOrder.Descending,
|
|
528
628
|
},
|
|
529
629
|
props: {
|
|
530
630
|
isRoot: true,
|