@oneuptime/common 9.5.3 → 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.
Files changed (149) hide show
  1. package/Models/DatabaseModels/Alert.ts +27 -0
  2. package/Models/DatabaseModels/AlertEpisode.ts +26 -0
  3. package/Models/DatabaseModels/Incident.ts +27 -0
  4. package/Models/DatabaseModels/IncidentEpisode.ts +26 -0
  5. package/Models/DatabaseModels/Project.ts +250 -0
  6. package/Models/DatabaseModels/ScheduledMaintenance.ts +27 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.ts +57 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.ts +83 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  10. package/Server/Services/AlertEpisodeMemberService.ts +6 -3
  11. package/Server/Services/AlertEpisodeService.ts +45 -97
  12. package/Server/Services/AlertEpisodeStateTimelineService.ts +4 -2
  13. package/Server/Services/AlertInternalNoteService.ts +5 -2
  14. package/Server/Services/AlertOwnerTeamService.ts +10 -4
  15. package/Server/Services/AlertOwnerUserService.ts +10 -4
  16. package/Server/Services/AlertService.ts +24 -38
  17. package/Server/Services/AlertStateTimelineService.ts +6 -3
  18. package/Server/Services/DatabaseService.ts +12 -0
  19. package/Server/Services/IncidentEpisodeMemberService.ts +8 -4
  20. package/Server/Services/IncidentEpisodePublicNoteService.ts +9 -6
  21. package/Server/Services/IncidentEpisodeService.ts +65 -117
  22. package/Server/Services/IncidentEpisodeStateTimelineService.ts +4 -2
  23. package/Server/Services/IncidentInternalNoteService.ts +10 -5
  24. package/Server/Services/IncidentMemberService.ts +20 -10
  25. package/Server/Services/IncidentOwnerTeamService.ts +20 -10
  26. package/Server/Services/IncidentOwnerUserService.ts +20 -10
  27. package/Server/Services/IncidentPublicNoteService.ts +10 -5
  28. package/Server/Services/IncidentService.ts +34 -110
  29. package/Server/Services/IncidentStateTimelineService.ts +11 -6
  30. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +61 -39
  31. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +31 -19
  32. package/Server/Services/ProjectService.ts +227 -0
  33. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +9 -6
  34. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +9 -6
  35. package/Server/Services/ScheduledMaintenanceService.ts +27 -39
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +8 -6
  37. package/Server/Services/UserNotificationRuleService.ts +32 -21
  38. package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +4 -2
  39. package/Server/Utils/Browser.ts +28 -20
  40. package/Server/Utils/Monitor/MonitorAlert.ts +5 -0
  41. package/Server/Utils/Monitor/MonitorIncident.ts +7 -0
  42. package/Server/Utils/PushNotificationUtil.ts +69 -26
  43. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +8 -4
  44. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +20 -8
  45. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +42 -22
  46. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +23 -17
  47. package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +1 -0
  48. package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +1 -0
  49. package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +1 -0
  50. package/Types/Monitor/MonitorEvaluationSummary.ts +2 -0
  51. package/Utils/Analytics.ts +11 -0
  52. package/build/dist/Models/DatabaseModels/Alert.js +29 -0
  53. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  54. package/build/dist/Models/DatabaseModels/AlertEpisode.js +28 -0
  55. package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -1
  56. package/build/dist/Models/DatabaseModels/Incident.js +29 -0
  57. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  58. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +28 -0
  59. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  60. package/build/dist/Models/DatabaseModels/Project.js +265 -0
  61. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  62. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +28 -0
  63. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  64. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js +27 -0
  65. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js.map +1 -0
  66. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js +34 -0
  67. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js.map +1 -0
  68. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  69. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  70. package/build/dist/Server/Services/AlertEpisodeMemberService.js +6 -3
  71. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  72. package/build/dist/Server/Services/AlertEpisodeService.js +33 -90
  73. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  74. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +3 -2
  75. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  76. package/build/dist/Server/Services/AlertInternalNoteService.js +2 -2
  77. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  78. package/build/dist/Server/Services/AlertOwnerTeamService.js +4 -4
  79. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
  80. package/build/dist/Server/Services/AlertOwnerUserService.js +4 -4
  81. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
  82. package/build/dist/Server/Services/AlertService.js +16 -34
  83. package/build/dist/Server/Services/AlertService.js.map +1 -1
  84. package/build/dist/Server/Services/AlertStateTimelineService.js +3 -3
  85. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  86. package/build/dist/Server/Services/DatabaseService.js +9 -0
  87. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  88. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
  89. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  90. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +4 -3
  91. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  92. package/build/dist/Server/Services/IncidentEpisodeService.js +46 -103
  93. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  94. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +3 -2
  95. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  96. package/build/dist/Server/Services/IncidentInternalNoteService.js +4 -2
  97. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  98. package/build/dist/Server/Services/IncidentMemberService.js +8 -4
  99. package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
  100. package/build/dist/Server/Services/IncidentOwnerTeamService.js +8 -4
  101. package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
  102. package/build/dist/Server/Services/IncidentOwnerUserService.js +8 -4
  103. package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
  104. package/build/dist/Server/Services/IncidentPublicNoteService.js +4 -2
  105. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  106. package/build/dist/Server/Services/IncidentService.js +24 -94
  107. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  108. package/build/dist/Server/Services/IncidentStateTimelineService.js +5 -3
  109. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  110. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +20 -16
  111. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  112. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +10 -8
  113. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  114. package/build/dist/Server/Services/ProjectService.js +207 -0
  115. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  116. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +4 -3
  117. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  118. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +4 -3
  119. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  120. package/build/dist/Server/Services/ScheduledMaintenanceService.js +16 -37
  121. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  122. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +3 -3
  123. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  124. package/build/dist/Server/Services/UserNotificationRuleService.js +33 -25
  125. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  126. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +4 -2
  127. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
  128. package/build/dist/Server/Utils/Browser.js +19 -12
  129. package/build/dist/Server/Utils/Browser.js.map +1 -1
  130. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +4 -0
  131. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  132. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +4 -0
  133. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  134. package/build/dist/Server/Utils/PushNotificationUtil.js +36 -28
  135. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  136. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +8 -4
  137. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  138. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +8 -8
  139. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  140. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +18 -10
  141. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  142. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +8 -8
  143. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  144. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -1
  145. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -1
  146. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -1
  147. package/build/dist/Utils/Analytics.js +5 -0
  148. package/build/dist/Utils/Analytics.js.map +1 -1
  149. package/package.json +1 -1
@@ -34,11 +34,11 @@ import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
34
34
  import NotificationRuleWorkspaceChannel from "../../Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel";
35
35
  import WorkspaceType from "../../Types/Workspace/WorkspaceType";
36
36
  import IncidentService from "./IncidentService";
37
- import Semaphore, { SemaphoreMutex } from "../Infrastructure/Semaphore";
38
37
  import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
39
38
  import OnCallDutyPolicy from "../../Models/DatabaseModels/OnCallDutyPolicy";
40
39
  import UserNotificationEventType from "../../Types/UserNotification/UserNotificationEventType";
41
40
  import IncidentGroupingRuleService from "./IncidentGroupingRuleService";
41
+ import ProjectService from "./ProjectService";
42
42
  import IncidentGroupingRule from "../../Models/DatabaseModels/IncidentGroupingRule";
43
43
 
44
44
  export class Service extends DatabaseService<Model> {
@@ -49,32 +49,6 @@ export class Service extends DatabaseService<Model> {
49
49
  }
50
50
  }
51
51
 
52
- @CaptureSpan()
53
- public async getExistingEpisodeNumberForProject(data: {
54
- projectId: ObjectID;
55
- }): Promise<number> {
56
- const lastEpisode: Model | null = await this.findOneBy({
57
- query: {
58
- projectId: data.projectId,
59
- },
60
- select: {
61
- episodeNumber: true,
62
- },
63
- sort: {
64
- episodeNumber: SortOrder.Descending,
65
- },
66
- props: {
67
- isRoot: true,
68
- },
69
- });
70
-
71
- if (!lastEpisode) {
72
- return 0;
73
- }
74
-
75
- return lastEpisode.episodeNumber ? Number(lastEpisode.episodeNumber) : 0;
76
- }
77
-
78
52
  @CaptureSpan()
79
53
  protected override async onBeforeCreate(
80
54
  createBy: CreateBy<Model>,
@@ -88,108 +62,77 @@ export class Service extends DatabaseService<Model> {
88
62
  const projectId: ObjectID =
89
63
  createBy.props.tenantId || createBy.data.projectId!;
90
64
 
91
- let mutex: SemaphoreMutex | null = null;
65
+ // Get the created state for episodes
66
+ const incidentState: IncidentState | null =
67
+ await IncidentStateService.findOneBy({
68
+ query: {
69
+ projectId: projectId,
70
+ isCreatedState: true,
71
+ },
72
+ select: {
73
+ _id: true,
74
+ },
75
+ props: {
76
+ isRoot: true,
77
+ },
78
+ });
92
79
 
93
- try {
94
- // Acquire mutex to prevent race conditions when generating episode numbers
95
- try {
96
- mutex = await Semaphore.lock({
97
- key: projectId.toString(),
98
- namespace: "IncidentEpisode.create",
99
- });
100
- } catch (err) {
101
- logger.error(err);
102
- }
80
+ if (!incidentState || !incidentState.id) {
81
+ throw new BadDataException(
82
+ "Created incident state not found for this project. Please add created incident state from settings.",
83
+ );
84
+ }
103
85
 
104
- // Get the created state for episodes
105
- const incidentState: IncidentState | null =
106
- await IncidentStateService.findOneBy({
107
- query: {
108
- projectId: projectId,
109
- isCreatedState: true,
110
- },
86
+ createBy.data.currentIncidentStateId = incidentState.id;
87
+
88
+ // Auto-generate episode number
89
+ const episodeCounterResult: {
90
+ counter: number;
91
+ prefix: string | undefined;
92
+ } = await ProjectService.incrementAndGetIncidentEpisodeCounter(projectId);
93
+
94
+ createBy.data.episodeNumber = episodeCounterResult.counter;
95
+ createBy.data.episodeNumberWithPrefix = episodeCounterResult.prefix
96
+ ? `${episodeCounterResult.prefix}${episodeCounterResult.counter}`
97
+ : `#${episodeCounterResult.counter}`;
98
+
99
+ // Set initial lastIncidentAddedAt
100
+ if (!createBy.data.lastIncidentAddedAt) {
101
+ createBy.data.lastIncidentAddedAt = OneUptimeDate.getCurrentDate();
102
+ }
103
+
104
+ // Set declaredAt if not provided
105
+ if (!createBy.data.declaredAt) {
106
+ createBy.data.declaredAt = OneUptimeDate.getCurrentDate();
107
+ }
108
+
109
+ // Copy showEpisodeOnStatusPage from grouping rule if available
110
+ if (createBy.data.incidentGroupingRuleId) {
111
+ const groupingRule: IncidentGroupingRule | null =
112
+ await IncidentGroupingRuleService.findOneById({
113
+ id: createBy.data.incidentGroupingRuleId,
111
114
  select: {
112
- _id: true,
115
+ showEpisodeOnStatusPage: true,
113
116
  },
114
117
  props: {
115
118
  isRoot: true,
116
119
  },
117
120
  });
118
121
 
119
- if (!incidentState || !incidentState.id) {
120
- throw new BadDataException(
121
- "Created incident state not found for this project. Please add created incident state from settings.",
122
- );
123
- }
124
-
125
- createBy.data.currentIncidentStateId = incidentState.id;
126
-
127
- // Auto-generate episode number
128
- const episodeNumberForThisEpisode: number =
129
- (await this.getExistingEpisodeNumberForProject({
130
- projectId: projectId,
131
- })) + 1;
132
-
133
- createBy.data.episodeNumber = episodeNumberForThisEpisode;
134
-
135
- // Set initial lastIncidentAddedAt
136
- if (!createBy.data.lastIncidentAddedAt) {
137
- createBy.data.lastIncidentAddedAt = OneUptimeDate.getCurrentDate();
122
+ if (groupingRule) {
123
+ createBy.data.isVisibleOnStatusPage =
124
+ groupingRule.showEpisodeOnStatusPage ?? true;
138
125
  }
139
-
140
- // Set declaredAt if not provided
141
- if (!createBy.data.declaredAt) {
142
- createBy.data.declaredAt = OneUptimeDate.getCurrentDate();
143
- }
144
-
145
- // Copy showEpisodeOnStatusPage from grouping rule if available
146
- if (createBy.data.incidentGroupingRuleId) {
147
- const groupingRule: IncidentGroupingRule | null =
148
- await IncidentGroupingRuleService.findOneById({
149
- id: createBy.data.incidentGroupingRuleId,
150
- select: {
151
- showEpisodeOnStatusPage: true,
152
- },
153
- props: {
154
- isRoot: true,
155
- },
156
- });
157
-
158
- if (groupingRule) {
159
- createBy.data.isVisibleOnStatusPage =
160
- groupingRule.showEpisodeOnStatusPage ?? true;
161
- }
162
- }
163
-
164
- return { createBy, carryForward: { mutex } };
165
- } catch (error) {
166
- // Release the mutex if it was acquired and an error occurred
167
- if (mutex) {
168
- try {
169
- await Semaphore.release(mutex);
170
- } catch (err) {
171
- logger.error(err);
172
- }
173
- }
174
- throw error;
175
126
  }
127
+
128
+ return { createBy, carryForward: null };
176
129
  }
177
130
 
178
131
  @CaptureSpan()
179
132
  protected override async onCreateSuccess(
180
- onCreate: OnCreate<Model>,
133
+ _onCreate: OnCreate<Model>,
181
134
  createdItem: Model,
182
135
  ): Promise<Model> {
183
- // Release the mutex acquired in onBeforeCreate
184
- const mutex: SemaphoreMutex | null = onCreate.carryForward?.mutex || null;
185
- if (mutex) {
186
- try {
187
- await Semaphore.release(mutex);
188
- } catch (err) {
189
- logger.error(err);
190
- }
191
- }
192
-
193
136
  if (!createdItem.projectId) {
194
137
  throw new BadDataException("projectId is required");
195
138
  }
@@ -256,7 +199,7 @@ export class Service extends DatabaseService<Model> {
256
199
  return;
257
200
  }
258
201
 
259
- let feedInfoInMarkdown: string = `#### Episode ${episode.episodeNumber?.toString()} Created
202
+ let feedInfoInMarkdown: string = `#### Episode ${episode.episodeNumberWithPrefix || "#" + episode.episodeNumber?.toString()} Created
260
203
 
261
204
  **${episode.title || "No title provided."}**
262
205
 
@@ -1047,13 +990,15 @@ export class Service extends DatabaseService<Model> {
1047
990
  }
1048
991
 
1049
992
  @CaptureSpan()
1050
- public async getEpisodeNumber(data: {
1051
- episodeId: ObjectID;
1052
- }): Promise<number | null> {
993
+ public async getEpisodeNumber(data: { episodeId: ObjectID }): Promise<{
994
+ number: number | null;
995
+ numberWithPrefix: string | null;
996
+ }> {
1053
997
  const episode: Model | null = await this.findOneById({
1054
998
  id: data.episodeId,
1055
999
  select: {
1056
1000
  episodeNumber: true,
1001
+ episodeNumberWithPrefix: true,
1057
1002
  },
1058
1003
  props: {
1059
1004
  isRoot: true,
@@ -1064,7 +1009,10 @@ export class Service extends DatabaseService<Model> {
1064
1009
  throw new BadDataException("Episode not found.");
1065
1010
  }
1066
1011
 
1067
- return episode.episodeNumber ? Number(episode.episodeNumber) : null;
1012
+ return {
1013
+ number: episode.episodeNumber ? Number(episode.episodeNumber) : null,
1014
+ numberWithPrefix: episode.episodeNumberWithPrefix || null,
1015
+ };
1068
1016
  }
1069
1017
  }
1070
1018
 
@@ -358,13 +358,15 @@ export class Service extends DatabaseService<IncidentEpisodeStateTimeline> {
358
358
  id: createdItem.incidentEpisodeId,
359
359
  select: {
360
360
  episodeNumber: true,
361
+ episodeNumberWithPrefix: true,
361
362
  },
362
363
  props: {
363
364
  isRoot: true,
364
365
  },
365
366
  });
366
367
 
367
- const episodeNumber: number = episode?.episodeNumber || 0;
368
+ const episodeDisplayNumber: string =
369
+ episode?.episodeNumberWithPrefix || "#" + (episode?.episodeNumber || 0);
368
370
 
369
371
  await IncidentEpisodeFeedService.createIncidentEpisodeFeedItem({
370
372
  incidentEpisodeId: createdItem.incidentEpisodeId!,
@@ -374,7 +376,7 @@ export class Service extends DatabaseService<IncidentEpisodeStateTimeline> {
374
376
  displayColor: incidentState?.color,
375
377
  feedInfoInMarkdown:
376
378
  stateEmoji +
377
- ` Changed **Episode ${episodeNumber} State** to **` +
379
+ ` Changed **Episode ${episodeDisplayNumber} State** to **` +
378
380
  stateName +
379
381
  "**",
380
382
  moreInformationInMarkdown: createdItem.rootCause
@@ -85,10 +85,15 @@ export class Service extends DatabaseService<Model> {
85
85
 
86
86
  const incidentId: ObjectID = createdItem.incidentId!;
87
87
 
88
- const incidentNumber: number | null =
89
- await IncidentService.getIncidentNumber({
90
- incidentId: incidentId,
91
- });
88
+ const incidentNumberResult: {
89
+ number: number | null;
90
+ numberWithPrefix: string | null;
91
+ } = await IncidentService.getIncidentNumber({
92
+ incidentId: incidentId,
93
+ });
94
+ const incidentNumberDisplay: string =
95
+ incidentNumberResult.numberWithPrefix ||
96
+ "#" + incidentNumberResult.number;
92
97
 
93
98
  const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
94
99
  createdItem.id!,
@@ -102,7 +107,7 @@ export class Service extends DatabaseService<Model> {
102
107
  displayColor: Blue500,
103
108
  userId: userId || undefined,
104
109
 
105
- feedInfoInMarkdown: `📄 posted **private note** for this [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(createdItem.projectId!, incidentId)).toString()}):
110
+ feedInfoInMarkdown: `📄 posted **private note** for this [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(createdItem.projectId!, incidentId)).toString()}):
106
111
 
107
112
  ${(createdItem.note || "") + attachmentsMarkdown}
108
113
  `,
@@ -136,10 +136,15 @@ export class Service extends DatabaseService<Model> {
136
136
  }
137
137
  }
138
138
 
139
- const incidentNumber: number | null =
140
- await IncidentService.getIncidentNumber({
141
- incidentId: incidentId,
142
- });
139
+ const incidentNumberResult: {
140
+ number: number | null;
141
+ numberWithPrefix: string | null;
142
+ } = await IncidentService.getIncidentNumber({
143
+ incidentId: incidentId,
144
+ });
145
+ const incidentNumberDisplay: string =
146
+ incidentNumberResult.numberWithPrefix ||
147
+ "#" + incidentNumberResult.number;
143
148
 
144
149
  if (user && user.name) {
145
150
  await IncidentFeedService.createIncidentFeedItem({
@@ -147,7 +152,7 @@ export class Service extends DatabaseService<Model> {
147
152
  projectId: projectId,
148
153
  incidentFeedEventType: IncidentFeedEventType.IncidentMemberRemoved,
149
154
  displayColor: Red500,
150
- feedInfoInMarkdown: `👤 Removed **${user.name.toString()}** (${user.email?.toString()}) as **${roleName}** from [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}).`,
155
+ feedInfoInMarkdown: `👤 Removed **${user.name.toString()}** (${user.email?.toString()}) as **${roleName}** from [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}).`,
151
156
  userId: deleteByUserId || undefined,
152
157
  workspaceNotification: {
153
158
  sendWorkspaceNotification: true,
@@ -192,10 +197,15 @@ export class Service extends DatabaseService<Model> {
192
197
  }
193
198
  }
194
199
 
195
- const incidentNumber: number | null =
196
- await IncidentService.getIncidentNumber({
197
- incidentId: incidentId,
198
- });
200
+ const incidentNumberResult: {
201
+ number: number | null;
202
+ numberWithPrefix: string | null;
203
+ } = await IncidentService.getIncidentNumber({
204
+ incidentId: incidentId,
205
+ });
206
+ const incidentNumberDisplay: string =
207
+ incidentNumberResult.numberWithPrefix ||
208
+ "#" + incidentNumberResult.number;
199
209
 
200
210
  if (userId) {
201
211
  await IncidentFeedService.createIncidentFeedItem({
@@ -208,7 +218,7 @@ export class Service extends DatabaseService<Model> {
208
218
  userId: userId,
209
219
  projectId: projectId,
210
220
  },
211
- )}** as **${roleName}** to [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}).`,
221
+ )}** as **${roleName}** to [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}).`,
212
222
  userId: createdByUserId || undefined,
213
223
  workspaceNotification: {
214
224
  sendWorkspaceNotification: true,
@@ -72,10 +72,15 @@ export class Service extends DatabaseService<Model> {
72
72
  },
73
73
  });
74
74
 
75
- const incidentNumber: number | null =
76
- await IncidentService.getIncidentNumber({
77
- incidentId: incidentId,
78
- });
75
+ const incidentNumberResult: {
76
+ number: number | null;
77
+ numberWithPrefix: string | null;
78
+ } = await IncidentService.getIncidentNumber({
79
+ incidentId: incidentId,
80
+ });
81
+ const incidentNumberDisplay: string =
82
+ incidentNumberResult.numberWithPrefix ||
83
+ "#" + incidentNumberResult.number;
79
84
 
80
85
  if (team && team.name) {
81
86
  await IncidentFeedService.createIncidentFeedItem({
@@ -83,7 +88,7 @@ export class Service extends DatabaseService<Model> {
83
88
  projectId: projectId,
84
89
  incidentFeedEventType: IncidentFeedEventType.OwnerTeamRemoved,
85
90
  displayColor: Red500,
86
- feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Removed team **${team.name}** from the [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
91
+ feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Removed team **${team.name}** from the [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
87
92
  userId: deleteByUserId || undefined,
88
93
  workspaceNotification: {
89
94
  sendWorkspaceNotification: true,
@@ -122,17 +127,22 @@ export class Service extends DatabaseService<Model> {
122
127
  });
123
128
 
124
129
  if (team && team.name) {
125
- const incidentNumber: number | null =
126
- await IncidentService.getIncidentNumber({
127
- incidentId: incidentId,
128
- });
130
+ const incidentNumberResult: {
131
+ number: number | null;
132
+ numberWithPrefix: string | null;
133
+ } = await IncidentService.getIncidentNumber({
134
+ incidentId: incidentId,
135
+ });
136
+ const incidentNumberDisplay: string =
137
+ incidentNumberResult.numberWithPrefix ||
138
+ "#" + incidentNumberResult.number;
129
139
 
130
140
  await IncidentFeedService.createIncidentFeedItem({
131
141
  incidentId: incidentId,
132
142
  projectId: projectId,
133
143
  incidentFeedEventType: IncidentFeedEventType.OwnerTeamAdded,
134
144
  displayColor: Gray500,
135
- feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Added team **${team.name}** to the [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
145
+ feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Added team **${team.name}** to the [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
136
146
  userId: createdByUserId || undefined,
137
147
  workspaceNotification: {
138
148
  sendWorkspaceNotification: true,
@@ -73,10 +73,15 @@ export class Service extends DatabaseService<Model> {
73
73
  },
74
74
  });
75
75
 
76
- const incidentNumber: number | null =
77
- await IncidentService.getIncidentNumber({
78
- incidentId: incidentId,
79
- });
76
+ const incidentNumberResult: {
77
+ number: number | null;
78
+ numberWithPrefix: string | null;
79
+ } = await IncidentService.getIncidentNumber({
80
+ incidentId: incidentId,
81
+ });
82
+ const incidentNumberDisplay: string =
83
+ incidentNumberResult.numberWithPrefix ||
84
+ "#" + incidentNumberResult.number;
80
85
 
81
86
  if (user && user.name) {
82
87
  await IncidentFeedService.createIncidentFeedItem({
@@ -84,7 +89,7 @@ export class Service extends DatabaseService<Model> {
84
89
  projectId: projectId,
85
90
  incidentFeedEventType: IncidentFeedEventType.OwnerUserRemoved,
86
91
  displayColor: Red500,
87
- feedInfoInMarkdown: `👨🏻‍💻 Removed **${user.name.toString()}** (${user.email?.toString()}) from the [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
92
+ feedInfoInMarkdown: `👨🏻‍💻 Removed **${user.name.toString()}** (${user.email?.toString()}) from the [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
88
93
  userId: deleteByUserId || undefined,
89
94
  workspaceNotification: {
90
95
  sendWorkspaceNotification: true,
@@ -112,10 +117,15 @@ export class Service extends DatabaseService<Model> {
112
117
  createdItem.createdByUserId || onCreate.createBy.props.userId;
113
118
 
114
119
  if (incidentId && userId && projectId) {
115
- const incidentNumber: number | null =
116
- await IncidentService.getIncidentNumber({
117
- incidentId: incidentId,
118
- });
120
+ const incidentNumberResult: {
121
+ number: number | null;
122
+ numberWithPrefix: string | null;
123
+ } = await IncidentService.getIncidentNumber({
124
+ incidentId: incidentId,
125
+ });
126
+ const incidentNumberDisplay: string =
127
+ incidentNumberResult.numberWithPrefix ||
128
+ "#" + incidentNumberResult.number;
119
129
 
120
130
  if (userId) {
121
131
  await IncidentFeedService.createIncidentFeedItem({
@@ -128,7 +138,7 @@ export class Service extends DatabaseService<Model> {
128
138
  userId: userId,
129
139
  projectId: projectId,
130
140
  },
131
- )}** to the [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
141
+ )}** to the [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) as the owner.`,
132
142
  userId: createdByUserId || undefined,
133
143
  workspaceNotification: {
134
144
  sendWorkspaceNotification: true,
@@ -118,10 +118,15 @@ export class Service extends DatabaseService<Model> {
118
118
 
119
119
  const incidentId: ObjectID = createdItem.incidentId!;
120
120
  const projectId: ObjectID = createdItem.projectId!;
121
- const incidentNumber: number | null =
122
- await IncidentService.getIncidentNumber({
123
- incidentId: incidentId,
124
- });
121
+ const incidentNumberResult: {
122
+ number: number | null;
123
+ numberWithPrefix: string | null;
124
+ } = await IncidentService.getIncidentNumber({
125
+ incidentId: incidentId,
126
+ });
127
+ const incidentNumberDisplay: string =
128
+ incidentNumberResult.numberWithPrefix ||
129
+ "#" + incidentNumberResult.number;
125
130
 
126
131
  const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
127
132
  createdItem.id!,
@@ -134,7 +139,7 @@ export class Service extends DatabaseService<Model> {
134
139
  incidentFeedEventType: IncidentFeedEventType.PublicNote,
135
140
  displayColor: Indigo500,
136
141
  userId: userId || undefined,
137
- feedInfoInMarkdown: `📄 posted **public note** for this [Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) on status page:
142
+ feedInfoInMarkdown: `📄 posted **public note** for this [Incident ${incidentNumberDisplay}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) on status page:
138
143
 
139
144
  ${(createdItem.note || "") + attachmentsMarkdown}
140
145
  `,