@oneuptime/common 9.5.2 → 9.5.4
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 +28 -0
- package/Models/DatabaseModels/AlertEpisode.ts +27 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Incident.ts +28 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +182 -0
- package/Models/DatabaseModels/IncidentEpisodeFeed.ts +2 -0
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +611 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +84 -0
- package/Models/DatabaseModels/IncidentGroupingRule.ts +36 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -0
- package/Models/DatabaseModels/Project.ts +252 -1
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +28 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -0
- package/Models/DatabaseModels/StatusPage.ts +120 -0
- package/Server/API/IncidentEpisodePublicNoteAPI.ts +98 -0
- package/Server/API/StatusPageAPI.ts +1092 -45
- package/Server/Infrastructure/Postgres/SchemaMigrations/1770232207959-MigrationName.ts +181 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1770237245069-MigrationName.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.ts +57 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.ts +83 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Services/AlertEpisodeMemberService.ts +6 -3
- package/Server/Services/AlertEpisodeService.ts +45 -97
- package/Server/Services/AlertEpisodeStateTimelineService.ts +4 -2
- package/Server/Services/AlertInternalNoteService.ts +5 -2
- package/Server/Services/AlertOwnerTeamService.ts +10 -4
- package/Server/Services/AlertOwnerUserService.ts +10 -4
- package/Server/Services/AlertService.ts +24 -38
- package/Server/Services/AlertStateTimelineService.ts +6 -3
- package/Server/Services/DatabaseService.ts +12 -0
- package/Server/Services/IncidentEpisodeMemberService.ts +8 -4
- package/Server/Services/IncidentEpisodePublicNoteService.ts +257 -0
- package/Server/Services/IncidentEpisodeService.ts +67 -93
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +4 -2
- package/Server/Services/IncidentInternalNoteService.ts +10 -5
- package/Server/Services/IncidentMemberService.ts +20 -10
- package/Server/Services/IncidentOwnerTeamService.ts +20 -10
- package/Server/Services/IncidentOwnerUserService.ts +20 -10
- package/Server/Services/IncidentPublicNoteService.ts +10 -5
- package/Server/Services/IncidentService.ts +34 -110
- package/Server/Services/IncidentStateTimelineService.ts +11 -6
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +61 -39
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +31 -19
- package/Server/Services/ProjectService.ts +227 -0
- package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +9 -6
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +9 -6
- package/Server/Services/ScheduledMaintenanceService.ts +27 -39
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +8 -6
- package/Server/Services/UserNotificationRuleService.ts +32 -21
- package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +4 -2
- package/Server/Utils/Browser.ts +28 -20
- package/Server/Utils/Monitor/MonitorAlert.ts +5 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +13 -0
- package/Server/Utils/PushNotificationUtil.ts +69 -26
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +8 -4
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +20 -8
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +42 -22
- package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +23 -17
- package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +1 -0
- package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +1 -0
- package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +1 -0
- package/Types/Email/EmailTemplateType.ts +4 -0
- package/Types/Icon/IconProp.ts +172 -0
- package/Types/Monitor/CriteriaIncident.ts +2 -0
- package/Types/Monitor/MonitorEvaluationSummary.ts +2 -0
- package/Types/Permission.ts +40 -0
- package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +5 -0
- package/UI/Components/Icon/Icon.tsx +1333 -1
- package/Utils/Analytics.ts +11 -0
- package/build/dist/Models/DatabaseModels/Alert.js +30 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisode.js +29 -0
- package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +30 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +189 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +626 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +86 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +37 -0
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +267 -1
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +1 -0
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +29 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +126 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodePublicNoteAPI.js +68 -0
- package/build/dist/Server/API/IncidentEpisodePublicNoteAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +874 -47
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770232207959-MigrationName.js +68 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770232207959-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245069-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245069-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js +27 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeMemberService.js +6 -3
- package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +33 -90
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +3 -2
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AlertInternalNoteService.js +2 -2
- package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerTeamService.js +4 -4
- package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerUserService.js +4 -4
- package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +16 -34
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +3 -3
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +9 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +224 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js +47 -82
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +3 -2
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentInternalNoteService.js +4 -2
- package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentMemberService.js +8 -4
- package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerTeamService.js +8 -4
- package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerUserService.js +8 -4
- package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +4 -2
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +24 -94
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +5 -3
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +20 -16
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +10 -8
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +207 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +4 -3
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +4 -3
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +16 -37
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +3 -3
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +33 -25
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +4 -2
- package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Browser.js +19 -12
- package/build/dist/Server/Utils/Browser.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +4 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +9 -0
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/PushNotificationUtil.js +36 -28
- package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +8 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +8 -8
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +18 -10
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +8 -8
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +3 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +172 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaIncident.js +1 -0
- package/build/dist/Types/Monitor/CriteriaIncident.js.map +1 -1
- package/build/dist/Types/Permission.js +34 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +502 -1
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/Utils/Analytics.js +5 -0
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/package.json +1 -1
|
@@ -44,9 +44,6 @@ import Metric, {
|
|
|
44
44
|
import OneUptimeDate from "../../Types/Date";
|
|
45
45
|
import TelemetryUtil from "../Utils/Telemetry/Telemetry";
|
|
46
46
|
import logger from "../Utils/Logger";
|
|
47
|
-
import Semaphore, {
|
|
48
|
-
SemaphoreMutex,
|
|
49
|
-
} from "../../Server/Infrastructure/Semaphore";
|
|
50
47
|
import IncidentFeedService from "./IncidentFeedService";
|
|
51
48
|
import IncidentSlaService from "./IncidentSlaService";
|
|
52
49
|
import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
|
|
@@ -65,6 +62,7 @@ import MetricType from "../../Models/DatabaseModels/MetricType";
|
|
|
65
62
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
66
63
|
import OnCallDutyPolicy from "../../Models/DatabaseModels/OnCallDutyPolicy";
|
|
67
64
|
import Dictionary from "../../Types/Dictionary";
|
|
65
|
+
import ProjectService from "./ProjectService";
|
|
68
66
|
import IncidentTemplateService from "./IncidentTemplateService";
|
|
69
67
|
import IncidentTemplate from "../../Models/DatabaseModels/IncidentTemplate";
|
|
70
68
|
import LLMService, {
|
|
@@ -333,35 +331,6 @@ export class Service extends DatabaseService<Model> {
|
|
|
333
331
|
return incident;
|
|
334
332
|
}
|
|
335
333
|
|
|
336
|
-
@CaptureSpan()
|
|
337
|
-
public async getExistingIncidentNumberForProject(data: {
|
|
338
|
-
projectId: ObjectID;
|
|
339
|
-
}): Promise<number> {
|
|
340
|
-
// get last incident number.
|
|
341
|
-
const lastIncident: Model | null = await this.findOneBy({
|
|
342
|
-
query: {
|
|
343
|
-
projectId: data.projectId,
|
|
344
|
-
},
|
|
345
|
-
select: {
|
|
346
|
-
incidentNumber: true,
|
|
347
|
-
},
|
|
348
|
-
sort: {
|
|
349
|
-
createdAt: SortOrder.Descending,
|
|
350
|
-
},
|
|
351
|
-
props: {
|
|
352
|
-
isRoot: true,
|
|
353
|
-
},
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
if (!lastIncident) {
|
|
357
|
-
return 0;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return lastIncident.incidentNumber
|
|
361
|
-
? Number(lastIncident.incidentNumber)
|
|
362
|
-
: 0;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
334
|
protected override async onBeforeUpdate(
|
|
366
335
|
updateBy: UpdateBy<Model>,
|
|
367
336
|
): Promise<OnUpdate<Model>> {
|
|
@@ -593,39 +562,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
593
562
|
initialIncidentStateId = incidentState.id;
|
|
594
563
|
}
|
|
595
564
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
key: projectId.toString(),
|
|
601
|
-
namespace: "IncidentService.incident-create",
|
|
602
|
-
lockTimeout: 15000,
|
|
603
|
-
acquireTimeout: 20000,
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
logger.debug(
|
|
607
|
-
"Mutex acquired - IncidentService.incident-create " +
|
|
608
|
-
projectId.toString() +
|
|
609
|
-
" at " +
|
|
610
|
-
OneUptimeDate.getCurrentDateAsFormattedString(),
|
|
611
|
-
);
|
|
612
|
-
} catch (err) {
|
|
613
|
-
logger.debug(
|
|
614
|
-
"Mutex acquire failed - IncidentService.incident-create " +
|
|
615
|
-
projectId.toString() +
|
|
616
|
-
" at " +
|
|
617
|
-
OneUptimeDate.getCurrentDateAsFormattedString(),
|
|
618
|
-
);
|
|
619
|
-
logger.error(err);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
const incidentNumberForThisIncident: number =
|
|
623
|
-
(await this.getExistingIncidentNumberForProject({
|
|
624
|
-
projectId: projectId,
|
|
625
|
-
})) + 1;
|
|
565
|
+
const incidentCounterResult: {
|
|
566
|
+
counter: number;
|
|
567
|
+
prefix: string | undefined;
|
|
568
|
+
} = await ProjectService.incrementAndGetIncidentCounter(projectId);
|
|
626
569
|
|
|
627
570
|
createBy.data.currentIncidentStateId = initialIncidentStateId;
|
|
628
|
-
createBy.data.incidentNumber =
|
|
571
|
+
createBy.data.incidentNumber = incidentCounterResult.counter;
|
|
572
|
+
createBy.data.incidentNumberWithPrefix = incidentCounterResult.prefix
|
|
573
|
+
? `${incidentCounterResult.prefix}${incidentCounterResult.counter}`
|
|
574
|
+
: `#${incidentCounterResult.counter}`;
|
|
629
575
|
|
|
630
576
|
if (
|
|
631
577
|
(createBy.data.createdByUserId ||
|
|
@@ -672,9 +618,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
672
618
|
|
|
673
619
|
return {
|
|
674
620
|
createBy,
|
|
675
|
-
carryForward:
|
|
676
|
-
mutex: mutex,
|
|
677
|
-
},
|
|
621
|
+
carryForward: null,
|
|
678
622
|
};
|
|
679
623
|
}
|
|
680
624
|
|
|
@@ -698,6 +642,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
698
642
|
select: {
|
|
699
643
|
projectId: true,
|
|
700
644
|
incidentNumber: true,
|
|
645
|
+
incidentNumberWithPrefix: true,
|
|
701
646
|
title: true,
|
|
702
647
|
description: true,
|
|
703
648
|
incidentSeverity: {
|
|
@@ -731,9 +676,6 @@ export class Service extends DatabaseService<Model> {
|
|
|
731
676
|
throw new BadDataException("Incident not found");
|
|
732
677
|
}
|
|
733
678
|
|
|
734
|
-
// Release mutex immediately
|
|
735
|
-
this.releaseMutexAsync(onCreate, createdItem.projectId!);
|
|
736
|
-
|
|
737
679
|
// Execute operations sequentially with error handling
|
|
738
680
|
Promise.resolve()
|
|
739
681
|
.then(async () => {
|
|
@@ -928,7 +870,11 @@ export class Service extends DatabaseService<Model> {
|
|
|
928
870
|
const createdByUserId: ObjectID | undefined | null =
|
|
929
871
|
incident.createdByUserId || incident.createdByUser?.id;
|
|
930
872
|
|
|
931
|
-
|
|
873
|
+
const incidentNumberDisplay: string =
|
|
874
|
+
incident.incidentNumberWithPrefix ||
|
|
875
|
+
"#" + incident.incidentNumber?.toString();
|
|
876
|
+
|
|
877
|
+
let feedInfoInMarkdown: string = `#### 🚨 Incident ${incidentNumberDisplay} Created:
|
|
932
878
|
|
|
933
879
|
**${incident.title || "No title provided."}**:
|
|
934
880
|
|
|
@@ -1082,8 +1028,9 @@ ${incident.remediationNotes || "No remediation notes provided."}
|
|
|
1082
1028
|
createdItem.changeMonitorStatusToId,
|
|
1083
1029
|
true, // notifyMonitorOwners
|
|
1084
1030
|
createdItem.rootCause ||
|
|
1085
|
-
"Status was changed because Incident
|
|
1086
|
-
createdItem.
|
|
1031
|
+
"Status was changed because Incident " +
|
|
1032
|
+
(createdItem.incidentNumberWithPrefix ||
|
|
1033
|
+
"#" + createdItem.incidentNumber?.toString()) +
|
|
1087
1034
|
" was created.",
|
|
1088
1035
|
createdItem.createdStateLog,
|
|
1089
1036
|
onCreate.createBy.props,
|
|
@@ -1095,37 +1042,6 @@ ${incident.remediationNotes || "No remediation notes provided."}
|
|
|
1095
1042
|
}
|
|
1096
1043
|
}
|
|
1097
1044
|
|
|
1098
|
-
@CaptureSpan()
|
|
1099
|
-
private releaseMutexAsync(
|
|
1100
|
-
onCreate: OnCreate<Model>,
|
|
1101
|
-
projectId: ObjectID,
|
|
1102
|
-
): void {
|
|
1103
|
-
// Release mutex in background without blocking
|
|
1104
|
-
if (onCreate.carryForward && onCreate.carryForward.mutex) {
|
|
1105
|
-
const mutex: SemaphoreMutex = onCreate.carryForward.mutex;
|
|
1106
|
-
|
|
1107
|
-
setImmediate(async () => {
|
|
1108
|
-
try {
|
|
1109
|
-
await Semaphore.release(mutex);
|
|
1110
|
-
logger.debug(
|
|
1111
|
-
"Mutex released - IncidentService.incident-create " +
|
|
1112
|
-
projectId.toString() +
|
|
1113
|
-
" at " +
|
|
1114
|
-
OneUptimeDate.getCurrentDateAsFormattedString(),
|
|
1115
|
-
);
|
|
1116
|
-
} catch (err) {
|
|
1117
|
-
logger.debug(
|
|
1118
|
-
"Mutex release failed - IncidentService.incident-create " +
|
|
1119
|
-
projectId.toString() +
|
|
1120
|
-
" at " +
|
|
1121
|
-
OneUptimeDate.getCurrentDateAsFormattedString(),
|
|
1122
|
-
);
|
|
1123
|
-
logger.error(err);
|
|
1124
|
-
}
|
|
1125
|
-
});
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
1045
|
@CaptureSpan()
|
|
1130
1046
|
public async disableActiveMonitoringIfManualIncident(
|
|
1131
1047
|
incidentId: ObjectID,
|
|
@@ -1351,6 +1267,7 @@ ${incident.remediationNotes || "No remediation notes provided."}
|
|
|
1351
1267
|
select: {
|
|
1352
1268
|
projectId: true,
|
|
1353
1269
|
incidentNumber: true,
|
|
1270
|
+
incidentNumberWithPrefix: true,
|
|
1354
1271
|
},
|
|
1355
1272
|
props: {
|
|
1356
1273
|
isRoot: true,
|
|
@@ -1359,7 +1276,9 @@ ${incident.remediationNotes || "No remediation notes provided."}
|
|
|
1359
1276
|
|
|
1360
1277
|
const projectId: ObjectID = incident!.projectId!;
|
|
1361
1278
|
const incidentNumber: number = incident!.incidentNumber!;
|
|
1362
|
-
const
|
|
1279
|
+
const incidentNumberDisplay: string =
|
|
1280
|
+
incident!.incidentNumberWithPrefix || "#" + incidentNumber;
|
|
1281
|
+
const incidentLabel: string = `Incident ${incidentNumberDisplay}`;
|
|
1363
1282
|
const incidentLink: URL = await this.getIncidentLinkInDashboard(
|
|
1364
1283
|
projectId,
|
|
1365
1284
|
incidentId,
|
|
@@ -1700,8 +1619,8 @@ ${incidentSeverity.name}
|
|
|
1700
1619
|
}),
|
|
1701
1620
|
changeNewMonitorStatusTo,
|
|
1702
1621
|
true, // notifyMonitorOwners
|
|
1703
|
-
"Status was changed because Incident
|
|
1704
|
-
|
|
1622
|
+
"Status was changed because Incident " +
|
|
1623
|
+
incidentNumberDisplay +
|
|
1705
1624
|
" was updated.",
|
|
1706
1625
|
undefined,
|
|
1707
1626
|
onUpdate.updateBy.props,
|
|
@@ -2369,13 +2288,15 @@ ${incidentSeverity.name}
|
|
|
2369
2288
|
}
|
|
2370
2289
|
|
|
2371
2290
|
@CaptureSpan()
|
|
2372
|
-
public async getIncidentNumber(data: {
|
|
2373
|
-
|
|
2374
|
-
|
|
2291
|
+
public async getIncidentNumber(data: { incidentId: ObjectID }): Promise<{
|
|
2292
|
+
number: number | null;
|
|
2293
|
+
numberWithPrefix: string | null;
|
|
2294
|
+
}> {
|
|
2375
2295
|
const incident: Model | null = await this.findOneById({
|
|
2376
2296
|
id: data.incidentId,
|
|
2377
2297
|
select: {
|
|
2378
2298
|
incidentNumber: true,
|
|
2299
|
+
incidentNumberWithPrefix: true,
|
|
2379
2300
|
},
|
|
2380
2301
|
props: {
|
|
2381
2302
|
isRoot: true,
|
|
@@ -2386,7 +2307,10 @@ ${incidentSeverity.name}
|
|
|
2386
2307
|
throw new BadDataException("Incident not found.");
|
|
2387
2308
|
}
|
|
2388
2309
|
|
|
2389
|
-
return
|
|
2310
|
+
return {
|
|
2311
|
+
number: incident.incidentNumber ? Number(incident.incidentNumber) : null,
|
|
2312
|
+
numberWithPrefix: incident.incidentNumberWithPrefix || null,
|
|
2313
|
+
};
|
|
2390
2314
|
}
|
|
2391
2315
|
|
|
2392
2316
|
/**
|
|
@@ -426,10 +426,15 @@ export class Service extends DatabaseService<IncidentStateTimeline> {
|
|
|
426
426
|
stateEmoji = "🔴";
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
429
|
+
const incidentNumberResult: {
|
|
430
|
+
number: number | null;
|
|
431
|
+
numberWithPrefix: string | null;
|
|
432
|
+
} = await IncidentService.getIncidentNumber({
|
|
433
|
+
incidentId: createdItem.incidentId,
|
|
434
|
+
});
|
|
435
|
+
const incidentNumberDisplay: string =
|
|
436
|
+
incidentNumberResult.numberWithPrefix ||
|
|
437
|
+
"#" + incidentNumberResult.number;
|
|
433
438
|
|
|
434
439
|
const projectId: ObjectID = createdItem.projectId!;
|
|
435
440
|
const incidentId: ObjectID = createdItem.incidentId!;
|
|
@@ -441,7 +446,7 @@ export class Service extends DatabaseService<IncidentStateTimeline> {
|
|
|
441
446
|
displayColor: incidentState?.color,
|
|
442
447
|
feedInfoInMarkdown:
|
|
443
448
|
stateEmoji +
|
|
444
|
-
` Changed **[Incident ${
|
|
449
|
+
` Changed **[Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) State** to **` +
|
|
445
450
|
stateName +
|
|
446
451
|
"**",
|
|
447
452
|
moreInformationInMarkdown: `**Cause:**
|
|
@@ -549,7 +554,7 @@ ${createdItem.rootCause}`,
|
|
|
549
554
|
},
|
|
550
555
|
sendMessageBeforeArchiving: {
|
|
551
556
|
_type: "WorkspacePayloadMarkdown",
|
|
552
|
-
text: `**[Incident ${
|
|
557
|
+
text: `**[Incident ${incidentNumberDisplay}](${(
|
|
553
558
|
await IncidentService.getIncidentLinkInDashboard(
|
|
554
559
|
createdItem.projectId!,
|
|
555
560
|
createdItem.incidentId!,
|
package/Server/Services/Index.ts
CHANGED
|
@@ -181,6 +181,7 @@ import IncidentEpisodeRoleMemberService from "./IncidentEpisodeRoleMemberService
|
|
|
181
181
|
import IncidentEpisodeOwnerTeamService from "./IncidentEpisodeOwnerTeamService";
|
|
182
182
|
import IncidentEpisodeOwnerUserService from "./IncidentEpisodeOwnerUserService";
|
|
183
183
|
import IncidentEpisodeStateTimelineService from "./IncidentEpisodeStateTimelineService";
|
|
184
|
+
import IncidentEpisodePublicNoteService from "./IncidentEpisodePublicNoteService";
|
|
184
185
|
import AlertGroupingRuleService from "./AlertGroupingRuleService";
|
|
185
186
|
import IncidentSlaRuleService from "./IncidentSlaRuleService";
|
|
186
187
|
import IncidentSlaService from "./IncidentSlaService";
|
|
@@ -400,6 +401,7 @@ const services: Array<BaseService> = [
|
|
|
400
401
|
IncidentEpisodeOwnerTeamService,
|
|
401
402
|
IncidentEpisodeOwnerUserService,
|
|
402
403
|
IncidentEpisodeStateTimelineService,
|
|
404
|
+
IncidentEpisodePublicNoteService,
|
|
403
405
|
AlertGroupingRuleService,
|
|
404
406
|
IncidentSlaRuleService,
|
|
405
407
|
IncidentSlaService,
|
|
@@ -87,34 +87,46 @@ export class Service extends DatabaseService<Model> {
|
|
|
87
87
|
const projectId: ObjectID | undefined = createdItem.projectId;
|
|
88
88
|
const incidentId: ObjectID | undefined =
|
|
89
89
|
createdItem.triggeredByIncidentId;
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
const incidentNumberResult: {
|
|
91
|
+
number: number | null;
|
|
92
|
+
numberWithPrefix: string | null;
|
|
93
|
+
} = await IncidentService.getIncidentNumber({
|
|
94
|
+
incidentId: incidentId,
|
|
95
|
+
});
|
|
96
|
+
const incidentNumberDisplay: string =
|
|
97
|
+
incidentNumberResult.numberWithPrefix ||
|
|
98
|
+
"#" + incidentNumberResult.number;
|
|
99
|
+
incidentOrAlertLink = `[Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()})`;
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
if (createdItem.triggeredByAlertId) {
|
|
98
|
-
const
|
|
103
|
+
const alertNumberResult: {
|
|
104
|
+
number: number | null;
|
|
105
|
+
numberWithPrefix: string | null;
|
|
106
|
+
} = await AlertService.getAlertNumber({
|
|
99
107
|
alertId: createdItem.triggeredByAlertId,
|
|
100
108
|
});
|
|
101
|
-
incidentOrAlertLink = `[Alert ${
|
|
109
|
+
incidentOrAlertLink = `[Alert ${alertNumberResult.numberWithPrefix || "#" + alertNumberResult.number}](${(await AlertService.getAlertLinkInDashboard(createdItem.projectId!, createdItem.triggeredByAlertId)).toString()})`;
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
if (createdItem.triggeredByAlertEpisodeId) {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
const alertEpisodeNumberResult: {
|
|
114
|
+
number: number | null;
|
|
115
|
+
numberWithPrefix: string | null;
|
|
116
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
117
|
+
episodeId: createdItem.triggeredByAlertEpisodeId,
|
|
118
|
+
});
|
|
119
|
+
incidentOrAlertLink = `[Alert Episode ${alertEpisodeNumberResult.numberWithPrefix || "#" + alertEpisodeNumberResult.number}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId!, createdItem.triggeredByAlertEpisodeId)).toString()})`;
|
|
110
120
|
}
|
|
111
121
|
|
|
112
122
|
if (createdItem.triggeredByIncidentEpisodeId) {
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
const incidentEpisodeNumberResult: {
|
|
124
|
+
number: number | null;
|
|
125
|
+
numberWithPrefix: string | null;
|
|
126
|
+
} = await IncidentEpisodeService.getEpisodeNumber({
|
|
127
|
+
episodeId: createdItem.triggeredByIncidentEpisodeId,
|
|
128
|
+
});
|
|
129
|
+
incidentOrAlertLink = `[Incident Episode ${incidentEpisodeNumberResult.numberWithPrefix || "#" + incidentEpisodeNumberResult.number}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId!, createdItem.triggeredByIncidentEpisodeId)).toString()})`;
|
|
118
130
|
}
|
|
119
131
|
|
|
120
132
|
const feedInfoInMarkdown: string = `**📞 On Call Policy Started Executing:** On Call Policy **${onCallPolicy.name}** started executing for ${incidentOrAlertLink}. Users on call on this policy will now be notified.`;
|
|
@@ -366,37 +378,47 @@ export class Service extends DatabaseService<Model> {
|
|
|
366
378
|
onCalldutyPolicyExecutionLog.projectId;
|
|
367
379
|
const incidentId: ObjectID | undefined =
|
|
368
380
|
onCalldutyPolicyExecutionLog.triggeredByIncidentId;
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
381
|
+
const incidentNumberResult: {
|
|
382
|
+
number: number | null;
|
|
383
|
+
numberWithPrefix: string | null;
|
|
384
|
+
} = await IncidentService.getIncidentNumber({
|
|
385
|
+
incidentId: incidentId,
|
|
386
|
+
});
|
|
387
|
+
const incidentNumberDisplay: string =
|
|
388
|
+
incidentNumberResult.numberWithPrefix ||
|
|
389
|
+
"#" + incidentNumberResult.number;
|
|
390
|
+
incidentOrAlertLink = `[Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()})`;
|
|
374
391
|
}
|
|
375
392
|
|
|
376
393
|
if (onCalldutyPolicyExecutionLog.triggeredByAlertId) {
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
394
|
+
const alertNumberResult: {
|
|
395
|
+
number: number | null;
|
|
396
|
+
numberWithPrefix: string | null;
|
|
397
|
+
} = await AlertService.getAlertNumber({
|
|
398
|
+
alertId: onCalldutyPolicyExecutionLog.triggeredByAlertId,
|
|
399
|
+
});
|
|
400
|
+
incidentOrAlertLink = `[Alert ${alertNumberResult.numberWithPrefix || "#" + alertNumberResult.number}](${(await AlertService.getAlertLinkInDashboard(onCalldutyPolicyExecutionLog.projectId!, onCalldutyPolicyExecutionLog.triggeredByAlertId)).toString()})`;
|
|
382
401
|
}
|
|
383
402
|
|
|
384
403
|
if (onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId) {
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
404
|
+
const alertEpisodeNumberResult: {
|
|
405
|
+
number: number | null;
|
|
406
|
+
numberWithPrefix: string | null;
|
|
407
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
408
|
+
episodeId: onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId,
|
|
409
|
+
});
|
|
410
|
+
incidentOrAlertLink = `[Alert Episode ${alertEpisodeNumberResult.numberWithPrefix || "#" + alertEpisodeNumberResult.number}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(onCalldutyPolicyExecutionLog.projectId!, onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId)).toString()})`;
|
|
391
411
|
}
|
|
392
412
|
|
|
393
413
|
if (onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId) {
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
414
|
+
const incidentEpisodeNumberResult: {
|
|
415
|
+
number: number | null;
|
|
416
|
+
numberWithPrefix: string | null;
|
|
417
|
+
} = await IncidentEpisodeService.getEpisodeNumber({
|
|
418
|
+
episodeId:
|
|
419
|
+
onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId,
|
|
420
|
+
});
|
|
421
|
+
incidentOrAlertLink = `[Incident Episode ${incidentEpisodeNumberResult.numberWithPrefix || "#" + incidentEpisodeNumberResult.number}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(onCalldutyPolicyExecutionLog.projectId!, onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId)).toString()})`;
|
|
400
422
|
}
|
|
401
423
|
|
|
402
424
|
const feedInfoInMarkdown: string = `**${this.getEmojiByStatus(onCalldutyPolicyExecutionLog.status)} On Call Policy Status Updated for ${incidentOrAlertLink}:**
|
|
@@ -167,36 +167,48 @@ export class Service extends DatabaseService<Model> {
|
|
|
167
167
|
onCallDutyPolicyExecutionLogTimeline.projectId;
|
|
168
168
|
const incidentId: ObjectID | undefined =
|
|
169
169
|
onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentId;
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
const incidentNumberResult: {
|
|
171
|
+
number: number | null;
|
|
172
|
+
numberWithPrefix: string | null;
|
|
173
|
+
} = await IncidentService.getIncidentNumber({
|
|
174
|
+
incidentId: incidentId,
|
|
175
|
+
});
|
|
176
|
+
const incidentNumberDisplay: string =
|
|
177
|
+
incidentNumberResult.numberWithPrefix ||
|
|
178
|
+
"#" + incidentNumberResult.number;
|
|
179
|
+
incidentOrAlertLink = `[Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()})`;
|
|
175
180
|
}
|
|
176
181
|
|
|
177
182
|
if (onCallDutyPolicyExecutionLogTimeline.triggeredByAlertId) {
|
|
178
|
-
const
|
|
183
|
+
const alertNumberResult: {
|
|
184
|
+
number: number | null;
|
|
185
|
+
numberWithPrefix: string | null;
|
|
186
|
+
} = await AlertService.getAlertNumber({
|
|
179
187
|
alertId: onCallDutyPolicyExecutionLogTimeline.triggeredByAlertId,
|
|
180
188
|
});
|
|
181
|
-
incidentOrAlertLink = `[Alert ${
|
|
189
|
+
incidentOrAlertLink = `[Alert ${alertNumberResult.numberWithPrefix || "#" + alertNumberResult.number}](${(await AlertService.getAlertLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByAlertId)).toString()})`;
|
|
182
190
|
}
|
|
183
191
|
|
|
184
192
|
if (onCallDutyPolicyExecutionLogTimeline.triggeredByAlertEpisodeId) {
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
193
|
+
const alertEpisodeNumberResult: {
|
|
194
|
+
number: number | null;
|
|
195
|
+
numberWithPrefix: string | null;
|
|
196
|
+
} = await AlertEpisodeService.getEpisodeNumber({
|
|
197
|
+
episodeId:
|
|
198
|
+
onCallDutyPolicyExecutionLogTimeline.triggeredByAlertEpisodeId,
|
|
199
|
+
});
|
|
200
|
+
incidentOrAlertLink = `[Alert Episode ${alertEpisodeNumberResult.numberWithPrefix || "#" + alertEpisodeNumberResult.number}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByAlertEpisodeId)).toString()})`;
|
|
191
201
|
}
|
|
192
202
|
|
|
193
203
|
if (onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentEpisodeId) {
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
204
|
+
const incidentEpisodeNumberResult: {
|
|
205
|
+
number: number | null;
|
|
206
|
+
numberWithPrefix: string | null;
|
|
207
|
+
} = await IncidentEpisodeService.getEpisodeNumber({
|
|
208
|
+
episodeId:
|
|
209
|
+
onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentEpisodeId,
|
|
210
|
+
});
|
|
211
|
+
incidentOrAlertLink = `[Incident Episode ${incidentEpisodeNumberResult.numberWithPrefix || "#" + incidentEpisodeNumberResult.number}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentEpisodeId)).toString()})`;
|
|
200
212
|
}
|
|
201
213
|
|
|
202
214
|
let feedInfoInMarkdown: string = `**${this.getEmojiBasedOnStatus(status)} ${incidentOrAlertLink} On-Call Alert ${status} to ${await UserService.getUserMarkdownString(
|