@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.
Files changed (218) hide show
  1. package/Models/DatabaseModels/Alert.ts +28 -0
  2. package/Models/DatabaseModels/AlertEpisode.ts +27 -0
  3. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
  4. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
  5. package/Models/DatabaseModels/Incident.ts +28 -0
  6. package/Models/DatabaseModels/IncidentEpisode.ts +182 -0
  7. package/Models/DatabaseModels/IncidentEpisodeFeed.ts +2 -0
  8. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +611 -0
  9. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +84 -0
  10. package/Models/DatabaseModels/IncidentGroupingRule.ts +36 -0
  11. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  12. package/Models/DatabaseModels/Index.ts +2 -0
  13. package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -0
  14. package/Models/DatabaseModels/Project.ts +252 -1
  15. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +1 -0
  16. package/Models/DatabaseModels/ScheduledMaintenance.ts +28 -0
  17. package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -0
  18. package/Models/DatabaseModels/StatusPage.ts +120 -0
  19. package/Server/API/IncidentEpisodePublicNoteAPI.ts +98 -0
  20. package/Server/API/StatusPageAPI.ts +1092 -45
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1770232207959-MigrationName.ts +181 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1770237245069-MigrationName.ts +35 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.ts +57 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.ts +83 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  26. package/Server/Services/AlertEpisodeMemberService.ts +6 -3
  27. package/Server/Services/AlertEpisodeService.ts +45 -97
  28. package/Server/Services/AlertEpisodeStateTimelineService.ts +4 -2
  29. package/Server/Services/AlertInternalNoteService.ts +5 -2
  30. package/Server/Services/AlertOwnerTeamService.ts +10 -4
  31. package/Server/Services/AlertOwnerUserService.ts +10 -4
  32. package/Server/Services/AlertService.ts +24 -38
  33. package/Server/Services/AlertStateTimelineService.ts +6 -3
  34. package/Server/Services/DatabaseService.ts +12 -0
  35. package/Server/Services/IncidentEpisodeMemberService.ts +8 -4
  36. package/Server/Services/IncidentEpisodePublicNoteService.ts +257 -0
  37. package/Server/Services/IncidentEpisodeService.ts +67 -93
  38. package/Server/Services/IncidentEpisodeStateTimelineService.ts +4 -2
  39. package/Server/Services/IncidentInternalNoteService.ts +10 -5
  40. package/Server/Services/IncidentMemberService.ts +20 -10
  41. package/Server/Services/IncidentOwnerTeamService.ts +20 -10
  42. package/Server/Services/IncidentOwnerUserService.ts +20 -10
  43. package/Server/Services/IncidentPublicNoteService.ts +10 -5
  44. package/Server/Services/IncidentService.ts +34 -110
  45. package/Server/Services/IncidentStateTimelineService.ts +11 -6
  46. package/Server/Services/Index.ts +2 -0
  47. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +61 -39
  48. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +31 -19
  49. package/Server/Services/ProjectService.ts +227 -0
  50. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +9 -6
  51. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +9 -6
  52. package/Server/Services/ScheduledMaintenanceService.ts +27 -39
  53. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +8 -6
  54. package/Server/Services/UserNotificationRuleService.ts +32 -21
  55. package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +4 -2
  56. package/Server/Utils/Browser.ts +28 -20
  57. package/Server/Utils/Monitor/MonitorAlert.ts +5 -0
  58. package/Server/Utils/Monitor/MonitorIncident.ts +13 -0
  59. package/Server/Utils/PushNotificationUtil.ts +69 -26
  60. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +8 -4
  61. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +20 -8
  62. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +42 -22
  63. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +23 -17
  64. package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +1 -0
  65. package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +1 -0
  66. package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +1 -0
  67. package/Types/Email/EmailTemplateType.ts +4 -0
  68. package/Types/Icon/IconProp.ts +172 -0
  69. package/Types/Monitor/CriteriaIncident.ts +2 -0
  70. package/Types/Monitor/MonitorEvaluationSummary.ts +2 -0
  71. package/Types/Permission.ts +40 -0
  72. package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +5 -0
  73. package/UI/Components/Icon/Icon.tsx +1333 -1
  74. package/Utils/Analytics.ts +11 -0
  75. package/build/dist/Models/DatabaseModels/Alert.js +30 -0
  76. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  77. package/build/dist/Models/DatabaseModels/AlertEpisode.js +29 -0
  78. package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -1
  79. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
  80. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
  81. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
  82. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  83. package/build/dist/Models/DatabaseModels/Incident.js +30 -0
  84. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  85. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +189 -0
  86. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  87. package/build/dist/Models/DatabaseModels/IncidentEpisodeFeed.js +2 -0
  88. package/build/dist/Models/DatabaseModels/IncidentEpisodeFeed.js.map +1 -1
  89. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +626 -0
  90. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -0
  91. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +86 -0
  92. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  93. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +37 -0
  94. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
  95. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  96. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  97. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  98. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  99. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -0
  100. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  101. package/build/dist/Models/DatabaseModels/Project.js +267 -1
  102. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  103. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +1 -0
  104. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  105. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +29 -0
  106. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  107. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -0
  108. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
  109. package/build/dist/Models/DatabaseModels/StatusPage.js +126 -0
  110. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  111. package/build/dist/Server/API/IncidentEpisodePublicNoteAPI.js +68 -0
  112. package/build/dist/Server/API/IncidentEpisodePublicNoteAPI.js.map +1 -0
  113. package/build/dist/Server/API/StatusPageAPI.js +874 -47
  114. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  115. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770232207959-MigrationName.js +68 -0
  116. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770232207959-MigrationName.js.map +1 -0
  117. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245069-MigrationName.js +18 -0
  118. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245069-MigrationName.js.map +1 -0
  119. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js +27 -0
  120. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js.map +1 -0
  121. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js +34 -0
  122. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js.map +1 -0
  123. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  124. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  125. package/build/dist/Server/Services/AlertEpisodeMemberService.js +6 -3
  126. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  127. package/build/dist/Server/Services/AlertEpisodeService.js +33 -90
  128. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  129. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +3 -2
  130. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  131. package/build/dist/Server/Services/AlertInternalNoteService.js +2 -2
  132. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  133. package/build/dist/Server/Services/AlertOwnerTeamService.js +4 -4
  134. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
  135. package/build/dist/Server/Services/AlertOwnerUserService.js +4 -4
  136. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
  137. package/build/dist/Server/Services/AlertService.js +16 -34
  138. package/build/dist/Server/Services/AlertService.js.map +1 -1
  139. package/build/dist/Server/Services/AlertStateTimelineService.js +3 -3
  140. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  141. package/build/dist/Server/Services/DatabaseService.js +9 -0
  142. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  143. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
  144. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  145. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +224 -0
  146. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -0
  147. package/build/dist/Server/Services/IncidentEpisodeService.js +47 -82
  148. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  149. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +3 -2
  150. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  151. package/build/dist/Server/Services/IncidentInternalNoteService.js +4 -2
  152. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  153. package/build/dist/Server/Services/IncidentMemberService.js +8 -4
  154. package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
  155. package/build/dist/Server/Services/IncidentOwnerTeamService.js +8 -4
  156. package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
  157. package/build/dist/Server/Services/IncidentOwnerUserService.js +8 -4
  158. package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
  159. package/build/dist/Server/Services/IncidentPublicNoteService.js +4 -2
  160. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  161. package/build/dist/Server/Services/IncidentService.js +24 -94
  162. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  163. package/build/dist/Server/Services/IncidentStateTimelineService.js +5 -3
  164. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  165. package/build/dist/Server/Services/Index.js +2 -0
  166. package/build/dist/Server/Services/Index.js.map +1 -1
  167. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +20 -16
  168. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  169. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +10 -8
  170. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  171. package/build/dist/Server/Services/ProjectService.js +207 -0
  172. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  173. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +4 -3
  174. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  175. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +4 -3
  176. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  177. package/build/dist/Server/Services/ScheduledMaintenanceService.js +16 -37
  178. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  179. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +3 -3
  180. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  181. package/build/dist/Server/Services/UserNotificationRuleService.js +33 -25
  182. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  183. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +4 -2
  184. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
  185. package/build/dist/Server/Utils/Browser.js +19 -12
  186. package/build/dist/Server/Utils/Browser.js.map +1 -1
  187. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +4 -0
  188. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  189. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +9 -0
  190. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  191. package/build/dist/Server/Utils/PushNotificationUtil.js +36 -28
  192. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  193. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +8 -4
  194. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  195. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +8 -8
  196. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  197. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +18 -10
  198. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  199. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +8 -8
  200. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  201. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -1
  202. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -1
  203. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -1
  204. package/build/dist/Types/Email/EmailTemplateType.js +3 -0
  205. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  206. package/build/dist/Types/Icon/IconProp.js +172 -0
  207. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  208. package/build/dist/Types/Monitor/CriteriaIncident.js +1 -0
  209. package/build/dist/Types/Monitor/CriteriaIncident.js.map +1 -1
  210. package/build/dist/Types/Permission.js +34 -0
  211. package/build/dist/Types/Permission.js.map +1 -1
  212. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
  213. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
  214. package/build/dist/UI/Components/Icon/Icon.js +502 -1
  215. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  216. package/build/dist/Utils/Analytics.js +5 -0
  217. package/build/dist/Utils/Analytics.js.map +1 -1
  218. 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
- let mutex: SemaphoreMutex | null = null;
597
-
598
- try {
599
- mutex = await Semaphore.lock({
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 = incidentNumberForThisIncident;
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
- let feedInfoInMarkdown: string = `#### 🚨 Incident ${incident.incidentNumber?.toString()} Created:
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.incidentNumber?.toString() +
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 incidentLabel: string = `Incident ${incidentNumber}`;
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
- incidentNumber?.toString() +
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
- incidentId: ObjectID;
2374
- }): Promise<number | null> {
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 incident.incidentNumber ? Number(incident.incidentNumber) : null;
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 incidentNumber: number | null =
430
- await IncidentService.getIncidentNumber({
431
- incidentId: createdItem.incidentId,
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 ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()}) State** to **` +
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 ${incidentNumber}](${(
557
+ text: `**[Incident ${incidentNumberDisplay}](${(
553
558
  await IncidentService.getIncidentLinkInDashboard(
554
559
  createdItem.projectId!,
555
560
  createdItem.incidentId!,
@@ -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 incidentNumber: number | null =
91
- await IncidentService.getIncidentNumber({
92
- incidentId: incidentId,
93
- });
94
- incidentOrAlertLink = `[Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()})`;
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 alertNumber: number | null = await AlertService.getAlertNumber({
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 ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(createdItem.projectId!, createdItem.triggeredByAlertId)).toString()})`;
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 episodeNumber: number | null =
106
- await AlertEpisodeService.getEpisodeNumber({
107
- episodeId: createdItem.triggeredByAlertEpisodeId,
108
- });
109
- incidentOrAlertLink = `[Alert Episode ${episodeNumber}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId!, createdItem.triggeredByAlertEpisodeId)).toString()})`;
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 episodeNumber: number | null =
114
- await IncidentEpisodeService.getEpisodeNumber({
115
- episodeId: createdItem.triggeredByIncidentEpisodeId,
116
- });
117
- incidentOrAlertLink = `[Incident Episode ${episodeNumber}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(createdItem.projectId!, createdItem.triggeredByIncidentEpisodeId)).toString()})`;
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 incidentNumber: number | null =
370
- await IncidentService.getIncidentNumber({
371
- incidentId: incidentId,
372
- });
373
- incidentOrAlertLink = `[Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()})`;
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 alertNumber: number | null =
378
- await AlertService.getAlertNumber({
379
- alertId: onCalldutyPolicyExecutionLog.triggeredByAlertId,
380
- });
381
- incidentOrAlertLink = `[Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(onCalldutyPolicyExecutionLog.projectId!, onCalldutyPolicyExecutionLog.triggeredByAlertId)).toString()})`;
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 episodeNumber: number | null =
386
- await AlertEpisodeService.getEpisodeNumber({
387
- episodeId:
388
- onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId,
389
- });
390
- incidentOrAlertLink = `[Alert Episode ${episodeNumber}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(onCalldutyPolicyExecutionLog.projectId!, onCalldutyPolicyExecutionLog.triggeredByAlertEpisodeId)).toString()})`;
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 episodeNumber: number | null =
395
- await IncidentEpisodeService.getEpisodeNumber({
396
- episodeId:
397
- onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId,
398
- });
399
- incidentOrAlertLink = `[Incident Episode ${episodeNumber}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(onCalldutyPolicyExecutionLog.projectId!, onCalldutyPolicyExecutionLog.triggeredByIncidentEpisodeId)).toString()})`;
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 incidentNumber: number | null =
171
- await IncidentService.getIncidentNumber({
172
- incidentId: incidentId,
173
- });
174
- incidentOrAlertLink = `[Incident ${incidentNumber}](${(await IncidentService.getIncidentLinkInDashboard(projectId!, incidentId!)).toString()})`;
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 alertNumber: number | null = await AlertService.getAlertNumber({
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 ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByAlertId)).toString()})`;
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 episodeNumber: number | null =
186
- await AlertEpisodeService.getEpisodeNumber({
187
- episodeId:
188
- onCallDutyPolicyExecutionLogTimeline.triggeredByAlertEpisodeId,
189
- });
190
- incidentOrAlertLink = `[Alert Episode ${episodeNumber}](${(await AlertEpisodeService.getEpisodeLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByAlertEpisodeId)).toString()})`;
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 episodeNumber: number | null =
195
- await IncidentEpisodeService.getEpisodeNumber({
196
- episodeId:
197
- onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentEpisodeId,
198
- });
199
- incidentOrAlertLink = `[Incident Episode ${episodeNumber}](${(await IncidentEpisodeService.getEpisodeLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentEpisodeId)).toString()})`;
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(