@oneuptime/common 9.5.7 → 9.5.9

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 (178) hide show
  1. package/Models/DatabaseModels/Alert.ts +8 -9
  2. package/Models/DatabaseModels/Incident.ts +5 -5
  3. package/Models/DatabaseModels/IncidentTemplate.ts +4 -3
  4. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +1 -1
  5. package/Models/DatabaseModels/UserOnCallLog.ts +1 -1
  6. package/Models/DatabaseModels/UserPush.ts +2 -1
  7. package/Server/API/UserPushAPI.ts +51 -4
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1770833704656-MigrationName.ts +156 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1770834237090-MigrationName.ts +119 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  11. package/Server/Middleware/UserAuthorization.ts +14 -9
  12. package/Server/Services/AlertEpisodeFeedService.ts +50 -0
  13. package/Server/Services/AlertEpisodeInternalNoteService.ts +162 -0
  14. package/Server/Services/AlertEpisodeMemberService.ts +7 -0
  15. package/Server/Services/AlertEpisodeOwnerTeamService.ts +186 -0
  16. package/Server/Services/AlertEpisodeOwnerUserService.ts +180 -0
  17. package/Server/Services/AlertEpisodeService.ts +68 -0
  18. package/Server/Services/AlertEpisodeStateTimelineService.ts +5 -0
  19. package/Server/Services/AlertService.ts +3 -0
  20. package/Server/Services/IncidentEpisodeFeedService.ts +50 -0
  21. package/Server/Services/IncidentEpisodeInternalNoteService.ts +163 -0
  22. package/Server/Services/IncidentEpisodeMemberService.ts +7 -0
  23. package/Server/Services/IncidentEpisodeOwnerTeamService.ts +189 -0
  24. package/Server/Services/IncidentEpisodeOwnerUserService.ts +183 -0
  25. package/Server/Services/IncidentEpisodePublicNoteService.ts +8 -0
  26. package/Server/Services/IncidentEpisodeService.ts +91 -12
  27. package/Server/Services/IncidentEpisodeStateTimelineService.ts +5 -0
  28. package/Server/Services/IncidentService.ts +5 -0
  29. package/Server/Services/PushNotificationService.ts +129 -27
  30. package/Server/Services/UserNotificationRuleService.ts +13 -3
  31. package/Server/Services/UserPushService.ts +2 -1
  32. package/Server/Services/WorkspaceNotificationRuleService.ts +20 -0
  33. package/Server/Utils/PushNotificationUtil.ts +56 -0
  34. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +1 -1
  35. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +7 -6
  36. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +1 -1
  37. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +7 -6
  38. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +17 -0
  39. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +27 -12
  40. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +17 -0
  41. package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +86 -28
  42. package/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.ts +6 -6
  43. package/Server/Utils/Workspace/Slack/Slack.ts +49 -0
  44. package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +2 -1
  45. package/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.ts +3 -1
  46. package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +2 -1
  47. package/Server/Utils/Workspace/WorkspaceMessages/IncidentEpisode.ts +3 -1
  48. package/Types/Permission.ts +641 -0
  49. package/Types/PushNotification/PushDeviceType.ts +7 -0
  50. package/Types/PushNotification/PushNotificationRequest.ts +3 -1
  51. package/UI/Components/Detail/Detail.tsx +13 -4
  52. package/UI/Components/Detail/Field.ts +2 -2
  53. package/UI/Components/Dropdown/Dropdown.tsx +38 -7
  54. package/UI/Components/Forms/BasicForm.tsx +35 -5
  55. package/UI/Components/Forms/Fields/PermissionPicker.tsx +261 -0
  56. package/UI/Components/Forms/Types/Field.ts +5 -3
  57. package/UI/Components/ModelDelete/ModelDelete.tsx +4 -1
  58. package/UI/Components/ModelDetail/CardModelDetail.tsx +4 -0
  59. package/UI/Components/ModelDetail/ModelDetail.tsx +4 -1
  60. package/UI/Components/Page/ModelPage.tsx +4 -1
  61. package/UI/Utils/Permission.ts +29 -6
  62. package/build/dist/Models/DatabaseModels/Alert.js +8 -8
  63. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  64. package/build/dist/Models/DatabaseModels/Incident.js +5 -5
  65. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  66. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +3 -3
  67. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  68. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +1 -1
  69. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  70. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +1 -1
  71. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  72. package/build/dist/Models/DatabaseModels/UserPush.js +2 -1
  73. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  74. package/build/dist/Server/API/UserPushAPI.js +34 -3
  75. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  76. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770833704656-MigrationName.js +63 -0
  77. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770833704656-MigrationName.js.map +1 -0
  78. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770834237090-MigrationName.js +46 -0
  79. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770834237090-MigrationName.js.map +1 -0
  80. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  82. package/build/dist/Server/Middleware/UserAuthorization.js +10 -4
  83. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  84. package/build/dist/Server/Services/AlertEpisodeFeedService.js +33 -0
  85. package/build/dist/Server/Services/AlertEpisodeFeedService.js.map +1 -1
  86. package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js +132 -0
  87. package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js.map +1 -1
  88. package/build/dist/Server/Services/AlertEpisodeMemberService.js +7 -0
  89. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  90. package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js +163 -0
  91. package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js.map +1 -1
  92. package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js +156 -0
  93. package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js.map +1 -1
  94. package/build/dist/Server/Services/AlertEpisodeService.js +53 -0
  95. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  96. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +4 -0
  97. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  98. package/build/dist/Server/Services/AlertService.js +3 -5
  99. package/build/dist/Server/Services/AlertService.js.map +1 -1
  100. package/build/dist/Server/Services/IncidentEpisodeFeedService.js +33 -0
  101. package/build/dist/Server/Services/IncidentEpisodeFeedService.js.map +1 -1
  102. package/build/dist/Server/Services/IncidentEpisodeInternalNoteService.js +132 -0
  103. package/build/dist/Server/Services/IncidentEpisodeInternalNoteService.js.map +1 -1
  104. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +7 -0
  105. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  106. package/build/dist/Server/Services/IncidentEpisodeOwnerTeamService.js +163 -0
  107. package/build/dist/Server/Services/IncidentEpisodeOwnerTeamService.js.map +1 -1
  108. package/build/dist/Server/Services/IncidentEpisodeOwnerUserService.js +156 -0
  109. package/build/dist/Server/Services/IncidentEpisodeOwnerUserService.js.map +1 -1
  110. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +8 -0
  111. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  112. package/build/dist/Server/Services/IncidentEpisodeService.js +72 -10
  113. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  114. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +4 -0
  115. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  116. package/build/dist/Server/Services/IncidentService.js +5 -5
  117. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  118. package/build/dist/Server/Services/PushNotificationService.js +77 -21
  119. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  120. package/build/dist/Server/Services/UserNotificationRuleService.js +12 -9
  121. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  122. package/build/dist/Server/Services/UserPushService.js +2 -1
  123. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  124. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +16 -0
  125. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  126. package/build/dist/Server/Utils/PushNotificationUtil.js +32 -8
  127. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  128. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +1 -1
  129. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  130. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +7 -6
  131. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  132. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +1 -1
  133. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  134. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +7 -6
  135. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  136. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +16 -0
  137. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  138. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +25 -9
  139. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
  140. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +16 -0
  141. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  142. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +71 -25
  143. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
  144. package/build/dist/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.js +6 -6
  145. package/build/dist/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.js.map +1 -1
  146. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +40 -0
  147. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  148. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js +1 -1
  149. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -1
  150. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js +1 -1
  151. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js.map +1 -1
  152. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js +1 -1
  153. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -1
  154. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/IncidentEpisode.js +1 -1
  155. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/IncidentEpisode.js.map +1 -1
  156. package/build/dist/Types/Permission.js +637 -0
  157. package/build/dist/Types/Permission.js.map +1 -1
  158. package/build/dist/Types/PushNotification/PushDeviceType.js +8 -0
  159. package/build/dist/Types/PushNotification/PushDeviceType.js.map +1 -0
  160. package/build/dist/UI/Components/Detail/Detail.js +7 -1
  161. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  162. package/build/dist/UI/Components/Dropdown/Dropdown.js +17 -2
  163. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  164. package/build/dist/UI/Components/Forms/BasicForm.js +17 -3
  165. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  166. package/build/dist/UI/Components/Forms/Fields/PermissionPicker.js +129 -0
  167. package/build/dist/UI/Components/Forms/Fields/PermissionPicker.js.map +1 -0
  168. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +2 -1
  169. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  170. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  171. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  172. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +2 -1
  173. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  174. package/build/dist/UI/Components/Page/ModelPage.js +2 -1
  175. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  176. package/build/dist/UI/Utils/Permission.js +17 -4
  177. package/build/dist/UI/Utils/Permission.js.map +1 -1
  178. package/package.json +2 -1
@@ -418,9 +418,8 @@ export default class Alert extends BaseModel {
418
418
  })
419
419
  @TableColumn({
420
420
  type: TableColumnType.ObjectID,
421
- title: "Deleted by User ID",
422
- description:
423
- "User ID who deleted this object (if this object was deleted by a User)",
421
+ title: "Monitor ID",
422
+ description: "ID of the monitor this alert belongs to",
424
423
  })
425
424
  @Column({
426
425
  type: ColumnType.ObjectID,
@@ -453,9 +452,9 @@ export default class Alert extends BaseModel {
453
452
  @TableColumn({
454
453
  required: false,
455
454
  type: TableColumnType.EntityArray,
456
- modelType: Monitor,
455
+ modelType: OnCallDutyPolicy,
457
456
  title: "On-Call Duty Policies",
458
- description: "List of on-call duty policy affected by this alert.",
457
+ description: "List of on-call duty policies affected by this alert.",
459
458
  })
460
459
  @ManyToMany(
461
460
  () => {
@@ -466,15 +465,15 @@ export default class Alert extends BaseModel {
466
465
  @JoinTable({
467
466
  name: "AlertOnCallDutyPolicy",
468
467
  inverseJoinColumn: {
469
- name: "monitorId",
468
+ name: "onCallDutyPolicyId",
470
469
  referencedColumnName: "_id",
471
470
  },
472
471
  joinColumn: {
473
- name: "onCallDutyPolicyId",
472
+ name: "alertId",
474
473
  referencedColumnName: "_id",
475
474
  },
476
475
  })
477
- public onCallDutyPolicies?: Array<OnCallDutyPolicy> = undefined; // monitors affected by this alert.
476
+ public onCallDutyPolicies?: Array<OnCallDutyPolicy> = undefined; // on-call duty policies affected by this alert.
478
477
 
479
478
  @ColumnAccessControl({
480
479
  create: [
@@ -701,7 +700,7 @@ export default class Alert extends BaseModel {
701
700
  @TableColumn({
702
701
  manyToOneRelationColumn: "monitorStatusWhenThisAlertWasCreatedId",
703
702
  type: TableColumnType.Entity,
704
- modelType: AlertState,
703
+ modelType: MonitorStatus,
705
704
  title: "Monitor status when this alert was created",
706
705
  description: "Monitor status when this alert was created",
707
706
  })
@@ -493,9 +493,9 @@ export default class Incident extends BaseModel {
493
493
  @TableColumn({
494
494
  required: false,
495
495
  type: TableColumnType.EntityArray,
496
- modelType: Monitor,
496
+ modelType: OnCallDutyPolicy,
497
497
  title: "On-Call Duty Policies",
498
- description: "List of on-call duty policy affected by this incident.",
498
+ description: "List of on-call duty policies affected by this incident.",
499
499
  })
500
500
  @ManyToMany(
501
501
  () => {
@@ -506,15 +506,15 @@ export default class Incident extends BaseModel {
506
506
  @JoinTable({
507
507
  name: "IncidentOnCallDutyPolicy",
508
508
  inverseJoinColumn: {
509
- name: "monitorId",
509
+ name: "onCallDutyPolicyId",
510
510
  referencedColumnName: "_id",
511
511
  },
512
512
  joinColumn: {
513
- name: "onCallDutyPolicyId",
513
+ name: "incidentId",
514
514
  referencedColumnName: "_id",
515
515
  },
516
516
  })
517
- public onCallDutyPolicies?: Array<OnCallDutyPolicy> = undefined; // monitors affected by this incident.
517
+ public onCallDutyPolicies?: Array<OnCallDutyPolicy> = undefined; // on-call duty policies affected by this incident.
518
518
 
519
519
  @ColumnAccessControl({
520
520
  create: [
@@ -522,9 +522,10 @@ export default class IncidentTemplate extends BaseModel {
522
522
  @TableColumn({
523
523
  required: false,
524
524
  type: TableColumnType.EntityArray,
525
- modelType: Monitor,
525
+ modelType: OnCallDutyPolicy,
526
526
  title: "On-Call Duty Policies",
527
- description: "List of on-call duty policy affected by this incident.",
527
+ description:
528
+ "List of on-call duty policies affected by this incident template.",
528
529
  })
529
530
  @ManyToMany(
530
531
  () => {
@@ -543,7 +544,7 @@ export default class IncidentTemplate extends BaseModel {
543
544
  referencedColumnName: "_id",
544
545
  },
545
546
  })
546
- public onCallDutyPolicies?: Array<OnCallDutyPolicy> = undefined; // monitors affected by this incident.
547
+ public onCallDutyPolicies?: Array<OnCallDutyPolicy> = undefined; // on-call duty policies affected by this incident template.
547
548
 
548
549
  @ColumnAccessControl({
549
550
  create: [
@@ -780,7 +780,7 @@ export default class OnCallDutyPolicyExecutionLog extends BaseModel {
780
780
  })
781
781
  @TableColumn({
782
782
  type: TableColumnType.ObjectID,
783
- title: "Deleted by User ID",
783
+ title: "Acknowledged by User ID",
784
784
  description:
785
785
  "User ID who acknowledged this object (if this object was acknowledged by a User)",
786
786
  example: "c3d4e5f6-a7b8-9012-cdef-123456789012",
@@ -766,7 +766,7 @@ export default class UserOnCallLog extends BaseModel {
766
766
  })
767
767
  @TableColumn({
768
768
  type: TableColumnType.ObjectID,
769
- title: "Deleted by User ID",
769
+ title: "Acknowledged by User ID",
770
770
  description:
771
771
  "User ID who acknowledged this object (if this object was acknowledged by a User)",
772
772
  example: "7c9d8e0f-a1b2-4c3d-9e5f-8a7b9c0d1e2f",
@@ -16,6 +16,7 @@ import TenantColumn from "../../Types/Database/TenantColumn";
16
16
  import IconProp from "../../Types/Icon/IconProp";
17
17
  import ObjectID from "../../Types/ObjectID";
18
18
  import Permission from "../../Types/Permission";
19
+ import PushDeviceType from "../../Types/PushNotification/PushDeviceType";
19
20
  import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
20
21
 
21
22
  @TenantColumn("projectId")
@@ -122,7 +123,7 @@ class UserPush extends BaseModel {
122
123
  unique: false,
123
124
  nullable: false,
124
125
  })
125
- public deviceType?: "web" = "web" as const; // Only web support for now
126
+ public deviceType?: PushDeviceType = undefined;
126
127
 
127
128
  @ColumnAccessControl({
128
129
  create: [Permission.CurrentUser],
@@ -14,6 +14,7 @@ import Response from "../Utils/Response";
14
14
  import BaseAPI from "./BaseAPI";
15
15
  import BadDataException from "../../Types/Exception/BadDataException";
16
16
  import ObjectID from "../../Types/ObjectID";
17
+ import PushDeviceType from "../../Types/PushNotification/PushDeviceType";
17
18
  import UserPush from "../../Models/DatabaseModels/UserPush";
18
19
  import PushNotificationMessage from "../../Types/PushNotification/PushNotificationMessage";
19
20
 
@@ -39,11 +40,17 @@ export default class UserPushAPI extends BaseAPI<
39
40
  );
40
41
  }
41
42
 
42
- if (!req.body.deviceType || req.body.deviceType !== "web") {
43
+ const validDeviceTypes: string[] = Object.values(PushDeviceType);
44
+ if (
45
+ !req.body.deviceType ||
46
+ !validDeviceTypes.includes(req.body.deviceType)
47
+ ) {
43
48
  return Response.sendErrorResponse(
44
49
  req,
45
50
  res,
46
- new BadDataException("Only web device type is supported"),
51
+ new BadDataException(
52
+ "Device type must be one of: " + validDeviceTypes.join(", "),
53
+ ),
47
54
  );
48
55
  }
49
56
 
@@ -86,7 +93,7 @@ export default class UserPushAPI extends BaseAPI<
86
93
  userPush.deviceToken = req.body.deviceToken;
87
94
  userPush.deviceType = req.body.deviceType;
88
95
  userPush.deviceName = req.body.deviceName || "Unknown Device";
89
- userPush.isVerified = true; // For web push, we consider it verified immediately
96
+ userPush.isVerified = true; // Web, iOS, and Android devices are verified immediately
90
97
 
91
98
  const savedDevice: UserPush = await this.service.create({
92
99
  data: userPush,
@@ -105,6 +112,46 @@ export default class UserPushAPI extends BaseAPI<
105
112
  },
106
113
  );
107
114
 
115
+ this.router.post(
116
+ `/user-push/unregister`,
117
+ UserMiddleware.getUserMiddleware,
118
+ async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
119
+ try {
120
+ req = req as OneUptimeRequest;
121
+
122
+ if (!req.body.deviceToken) {
123
+ return Response.sendErrorResponse(
124
+ req,
125
+ res,
126
+ new BadDataException("Device token is required"),
127
+ );
128
+ }
129
+
130
+ const userId: ObjectID = (req as OneUptimeRequest).userAuthorization!
131
+ .userId!;
132
+
133
+ await this.service.deleteBy({
134
+ query: {
135
+ userId: userId,
136
+ deviceToken: req.body.deviceToken,
137
+ },
138
+ limit: 100,
139
+ skip: 0,
140
+ props: {
141
+ isRoot: true,
142
+ },
143
+ });
144
+
145
+ return Response.sendJsonObjectResponse(req, res, {
146
+ success: true,
147
+ message: "Device unregistered successfully",
148
+ });
149
+ } catch (error) {
150
+ return next(error);
151
+ }
152
+ },
153
+ );
154
+
108
155
  this.router.post(
109
156
  `/user-push/:deviceId/test-notification`,
110
157
  UserMiddleware.getUserMiddleware,
@@ -186,7 +233,7 @@ export default class UserPushAPI extends BaseAPI<
186
233
  },
187
234
  ],
188
235
  message: testMessage,
189
- deviceType: device.deviceType!,
236
+ deviceType: device.deviceType! as PushDeviceType,
190
237
  },
191
238
  {
192
239
  isSensitive: false,
@@ -0,0 +1,156 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1770833704656 implements MigrationInterface {
4
+ public name = "MigrationName1770833704656";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ /*
8
+ * AlertOnCallDutyPolicy: fix column names
9
+ * Original columns: onCallDutyPolicyId (FK → Alert._id), monitorId (FK → OnCallDutyPolicy._id)
10
+ * Target columns: alertId (FK → Alert._id), onCallDutyPolicyId (FK → OnCallDutyPolicy._id)
11
+ * Must rename onCallDutyPolicyId first to free the name, then rename monitorId.
12
+ */
13
+
14
+ await queryRunner.query(
15
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_0eca13d28cf4d2349406ddebc5c"`,
16
+ );
17
+ await queryRunner.query(
18
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_1ef6702995a8406630f75f06e28"`,
19
+ );
20
+ await queryRunner.query(
21
+ `DROP INDEX "public"."IDX_0eca13d28cf4d2349406ddebc5"`,
22
+ );
23
+ await queryRunner.query(
24
+ `DROP INDEX "public"."IDX_1ef6702995a8406630f75f06e2"`,
25
+ );
26
+
27
+ await queryRunner.query(
28
+ `ALTER TABLE "AlertOnCallDutyPolicy" RENAME COLUMN "onCallDutyPolicyId" TO "alertId"`,
29
+ );
30
+ await queryRunner.query(
31
+ `ALTER TABLE "AlertOnCallDutyPolicy" RENAME COLUMN "monitorId" TO "onCallDutyPolicyId"`,
32
+ );
33
+
34
+ await queryRunner.query(
35
+ `CREATE INDEX "IDX_AlertOnCallDutyPolicy_alertId" ON "AlertOnCallDutyPolicy" ("alertId")`,
36
+ );
37
+ await queryRunner.query(
38
+ `CREATE INDEX "IDX_AlertOnCallDutyPolicy_onCallDutyPolicyId" ON "AlertOnCallDutyPolicy" ("onCallDutyPolicyId")`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_AlertOnCallDutyPolicy_alertId" FOREIGN KEY ("alertId") REFERENCES "Alert"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
42
+ );
43
+ await queryRunner.query(
44
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_AlertOnCallDutyPolicy_onCallDutyPolicyId" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
45
+ );
46
+
47
+ /*
48
+ * IncidentOnCallDutyPolicy: fix column names
49
+ * Original columns: onCallDutyPolicyId (FK → Incident._id), monitorId (FK → OnCallDutyPolicy._id)
50
+ * Target columns: incidentId (FK → Incident._id), onCallDutyPolicyId (FK → OnCallDutyPolicy._id)
51
+ */
52
+
53
+ await queryRunner.query(
54
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_2d127b6da0e4fab9f905b4d332d"`,
55
+ );
56
+ await queryRunner.query(
57
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_f89b23e3cafd1c6a0bfd42c297d"`,
58
+ );
59
+ await queryRunner.query(
60
+ `DROP INDEX "public"."IDX_2d127b6da0e4fab9f905b4d332"`,
61
+ );
62
+ await queryRunner.query(
63
+ `DROP INDEX "public"."IDX_f89b23e3cafd1c6a0bfd42c297"`,
64
+ );
65
+
66
+ await queryRunner.query(
67
+ `ALTER TABLE "IncidentOnCallDutyPolicy" RENAME COLUMN "onCallDutyPolicyId" TO "incidentId"`,
68
+ );
69
+ await queryRunner.query(
70
+ `ALTER TABLE "IncidentOnCallDutyPolicy" RENAME COLUMN "monitorId" TO "onCallDutyPolicyId"`,
71
+ );
72
+
73
+ await queryRunner.query(
74
+ `CREATE INDEX "IDX_IncidentOnCallDutyPolicy_incidentId" ON "IncidentOnCallDutyPolicy" ("incidentId")`,
75
+ );
76
+ await queryRunner.query(
77
+ `CREATE INDEX "IDX_IncidentOnCallDutyPolicy_onCallDutyPolicyId" ON "IncidentOnCallDutyPolicy" ("onCallDutyPolicyId")`,
78
+ );
79
+ await queryRunner.query(
80
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_IncidentOnCallDutyPolicy_incidentId" FOREIGN KEY ("incidentId") REFERENCES "Incident"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
81
+ );
82
+ await queryRunner.query(
83
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_IncidentOnCallDutyPolicy_onCallDutyPolicyId" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
84
+ );
85
+ }
86
+
87
+ public async down(queryRunner: QueryRunner): Promise<void> {
88
+ // Revert IncidentOnCallDutyPolicy
89
+ await queryRunner.query(
90
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_IncidentOnCallDutyPolicy_onCallDutyPolicyId"`,
91
+ );
92
+ await queryRunner.query(
93
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_IncidentOnCallDutyPolicy_incidentId"`,
94
+ );
95
+ await queryRunner.query(
96
+ `DROP INDEX "public"."IDX_IncidentOnCallDutyPolicy_onCallDutyPolicyId"`,
97
+ );
98
+ await queryRunner.query(
99
+ `DROP INDEX "public"."IDX_IncidentOnCallDutyPolicy_incidentId"`,
100
+ );
101
+
102
+ await queryRunner.query(
103
+ `ALTER TABLE "IncidentOnCallDutyPolicy" RENAME COLUMN "onCallDutyPolicyId" TO "monitorId"`,
104
+ );
105
+ await queryRunner.query(
106
+ `ALTER TABLE "IncidentOnCallDutyPolicy" RENAME COLUMN "incidentId" TO "onCallDutyPolicyId"`,
107
+ );
108
+
109
+ await queryRunner.query(
110
+ `CREATE INDEX "IDX_2d127b6da0e4fab9f905b4d332" ON "IncidentOnCallDutyPolicy" ("onCallDutyPolicyId")`,
111
+ );
112
+ await queryRunner.query(
113
+ `CREATE INDEX "IDX_f89b23e3cafd1c6a0bfd42c297" ON "IncidentOnCallDutyPolicy" ("monitorId")`,
114
+ );
115
+ await queryRunner.query(
116
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_2d127b6da0e4fab9f905b4d332d" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "Incident"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
117
+ );
118
+ await queryRunner.query(
119
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_f89b23e3cafd1c6a0bfd42c297d" FOREIGN KEY ("monitorId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
120
+ );
121
+
122
+ // Revert AlertOnCallDutyPolicy
123
+ await queryRunner.query(
124
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_AlertOnCallDutyPolicy_onCallDutyPolicyId"`,
125
+ );
126
+ await queryRunner.query(
127
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_AlertOnCallDutyPolicy_alertId"`,
128
+ );
129
+ await queryRunner.query(
130
+ `DROP INDEX "public"."IDX_AlertOnCallDutyPolicy_onCallDutyPolicyId"`,
131
+ );
132
+ await queryRunner.query(
133
+ `DROP INDEX "public"."IDX_AlertOnCallDutyPolicy_alertId"`,
134
+ );
135
+
136
+ await queryRunner.query(
137
+ `ALTER TABLE "AlertOnCallDutyPolicy" RENAME COLUMN "onCallDutyPolicyId" TO "monitorId"`,
138
+ );
139
+ await queryRunner.query(
140
+ `ALTER TABLE "AlertOnCallDutyPolicy" RENAME COLUMN "alertId" TO "onCallDutyPolicyId"`,
141
+ );
142
+
143
+ await queryRunner.query(
144
+ `CREATE INDEX "IDX_0eca13d28cf4d2349406ddebc5" ON "AlertOnCallDutyPolicy" ("onCallDutyPolicyId")`,
145
+ );
146
+ await queryRunner.query(
147
+ `CREATE INDEX "IDX_1ef6702995a8406630f75f06e2" ON "AlertOnCallDutyPolicy" ("monitorId")`,
148
+ );
149
+ await queryRunner.query(
150
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_0eca13d28cf4d2349406ddebc5c" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "Alert"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
151
+ );
152
+ await queryRunner.query(
153
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_1ef6702995a8406630f75f06e28" FOREIGN KEY ("monitorId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
154
+ );
155
+ }
156
+ }
@@ -0,0 +1,119 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1770834237090 implements MigrationInterface {
4
+ public name = "MigrationName1770834237090";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_IncidentOnCallDutyPolicy_incidentId"`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_IncidentOnCallDutyPolicy_onCallDutyPolicyId"`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_AlertOnCallDutyPolicy_alertId"`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_AlertOnCallDutyPolicy_onCallDutyPolicyId"`,
18
+ );
19
+ await queryRunner.query(
20
+ `DROP INDEX "public"."IDX_IncidentOnCallDutyPolicy_onCallDutyPolicyId"`,
21
+ );
22
+ await queryRunner.query(
23
+ `DROP INDEX "public"."IDX_IncidentOnCallDutyPolicy_incidentId"`,
24
+ );
25
+ await queryRunner.query(
26
+ `DROP INDEX "public"."IDX_AlertOnCallDutyPolicy_alertId"`,
27
+ );
28
+ await queryRunner.query(
29
+ `DROP INDEX "public"."IDX_AlertOnCallDutyPolicy_onCallDutyPolicyId"`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
33
+ );
34
+ await queryRunner.query(
35
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
36
+ );
37
+ await queryRunner.query(
38
+ `CREATE INDEX "IDX_47b1a29b40fc779495dd7ba407" ON "IncidentOnCallDutyPolicy" ("incidentId") `,
39
+ );
40
+ await queryRunner.query(
41
+ `CREATE INDEX "IDX_2d127b6da0e4fab9f905b4d332" ON "IncidentOnCallDutyPolicy" ("onCallDutyPolicyId") `,
42
+ );
43
+ await queryRunner.query(
44
+ `CREATE INDEX "IDX_359174b1e315a1600ddee16812" ON "AlertOnCallDutyPolicy" ("alertId") `,
45
+ );
46
+ await queryRunner.query(
47
+ `CREATE INDEX "IDX_0eca13d28cf4d2349406ddebc5" ON "AlertOnCallDutyPolicy" ("onCallDutyPolicyId") `,
48
+ );
49
+ await queryRunner.query(
50
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_47b1a29b40fc779495dd7ba4076" FOREIGN KEY ("incidentId") REFERENCES "Incident"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
51
+ );
52
+ await queryRunner.query(
53
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_2d127b6da0e4fab9f905b4d332d" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
54
+ );
55
+ await queryRunner.query(
56
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_359174b1e315a1600ddee168129" FOREIGN KEY ("alertId") REFERENCES "Alert"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_0eca13d28cf4d2349406ddebc5c" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
60
+ );
61
+ }
62
+
63
+ public async down(queryRunner: QueryRunner): Promise<void> {
64
+ await queryRunner.query(
65
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_0eca13d28cf4d2349406ddebc5c"`,
66
+ );
67
+ await queryRunner.query(
68
+ `ALTER TABLE "AlertOnCallDutyPolicy" DROP CONSTRAINT "FK_359174b1e315a1600ddee168129"`,
69
+ );
70
+ await queryRunner.query(
71
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_2d127b6da0e4fab9f905b4d332d"`,
72
+ );
73
+ await queryRunner.query(
74
+ `ALTER TABLE "IncidentOnCallDutyPolicy" DROP CONSTRAINT "FK_47b1a29b40fc779495dd7ba4076"`,
75
+ );
76
+ await queryRunner.query(
77
+ `DROP INDEX "public"."IDX_0eca13d28cf4d2349406ddebc5"`,
78
+ );
79
+ await queryRunner.query(
80
+ `DROP INDEX "public"."IDX_359174b1e315a1600ddee16812"`,
81
+ );
82
+ await queryRunner.query(
83
+ `DROP INDEX "public"."IDX_2d127b6da0e4fab9f905b4d332"`,
84
+ );
85
+ await queryRunner.query(
86
+ `DROP INDEX "public"."IDX_47b1a29b40fc779495dd7ba407"`,
87
+ );
88
+ await queryRunner.query(
89
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
90
+ );
91
+ await queryRunner.query(
92
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
93
+ );
94
+ await queryRunner.query(
95
+ `CREATE INDEX "IDX_AlertOnCallDutyPolicy_onCallDutyPolicyId" ON "AlertOnCallDutyPolicy" ("onCallDutyPolicyId") `,
96
+ );
97
+ await queryRunner.query(
98
+ `CREATE INDEX "IDX_AlertOnCallDutyPolicy_alertId" ON "AlertOnCallDutyPolicy" ("alertId") `,
99
+ );
100
+ await queryRunner.query(
101
+ `CREATE INDEX "IDX_IncidentOnCallDutyPolicy_incidentId" ON "IncidentOnCallDutyPolicy" ("incidentId") `,
102
+ );
103
+ await queryRunner.query(
104
+ `CREATE INDEX "IDX_IncidentOnCallDutyPolicy_onCallDutyPolicyId" ON "IncidentOnCallDutyPolicy" ("onCallDutyPolicyId") `,
105
+ );
106
+ await queryRunner.query(
107
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_AlertOnCallDutyPolicy_onCallDutyPolicyId" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
108
+ );
109
+ await queryRunner.query(
110
+ `ALTER TABLE "AlertOnCallDutyPolicy" ADD CONSTRAINT "FK_AlertOnCallDutyPolicy_alertId" FOREIGN KEY ("alertId") REFERENCES "Alert"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
111
+ );
112
+ await queryRunner.query(
113
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_IncidentOnCallDutyPolicy_onCallDutyPolicyId" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
114
+ );
115
+ await queryRunner.query(
116
+ `ALTER TABLE "IncidentOnCallDutyPolicy" ADD CONSTRAINT "FK_IncidentOnCallDutyPolicy_incidentId" FOREIGN KEY ("incidentId") REFERENCES "Incident"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
117
+ );
118
+ }
119
+ }
@@ -256,6 +256,8 @@ import { MigrationName1770407024682 } from "./1770407024682-MigrationName";
256
256
  import { MigrationName1770668054908 } from "./1770668054908-MigrationName";
257
257
  import { MigrationName1770728946893 } from "./1770728946893-MigrationName";
258
258
  import { MigrationName1770732721195 } from "./1770732721195-MigrationName";
259
+ import { MigrationName1770833704656 } from "./1770833704656-MigrationName";
260
+ import { MigrationName1770834237090 } from "./1770834237090-MigrationName";
259
261
 
260
262
  export default [
261
263
  InitialMigration,
@@ -516,4 +518,6 @@ export default [
516
518
  MigrationName1770668054908,
517
519
  MigrationName1770728946893,
518
520
  MigrationName1770732721195,
521
+ MigrationName1770833704656,
522
+ MigrationName1770834237090,
519
523
  ];
@@ -64,18 +64,23 @@ export default class UserMiddleware {
64
64
  public static getAccessTokenFromExpressRequest(
65
65
  req: ExpressRequest,
66
66
  ): string | undefined {
67
- let accessToken: string | undefined = undefined;
67
+ // 1. Try cookie (existing web dashboard flow)
68
+ const cookieToken: string | undefined =
69
+ CookieUtil.getCookieFromExpressRequest(req, CookieUtil.getUserTokenKey());
68
70
 
69
- if (
70
- CookieUtil.getCookieFromExpressRequest(req, CookieUtil.getUserTokenKey())
71
- ) {
72
- accessToken = CookieUtil.getCookieFromExpressRequest(
73
- req,
74
- CookieUtil.getUserTokenKey(),
75
- );
71
+ if (cookieToken) {
72
+ return cookieToken;
76
73
  }
77
74
 
78
- return accessToken;
75
+ // 2. Fallback: Check Authorization: Bearer <token> header (mobile app flow)
76
+ const authHeader: string | undefined = req.headers["authorization"] as
77
+ | string
78
+ | undefined;
79
+ if (authHeader && authHeader.startsWith("Bearer ")) {
80
+ return authHeader.substring(7);
81
+ }
82
+
83
+ return undefined;
79
84
  }
80
85
 
81
86
  @CaptureSpan()
@@ -9,6 +9,9 @@ import DatabaseService from "./DatabaseService";
9
9
  import Model, {
10
10
  AlertEpisodeFeedEventType,
11
11
  } from "../../Models/DatabaseModels/AlertEpisodeFeed";
12
+ import WorkspaceNotificationRuleService, {
13
+ MessageBlocksByWorkspaceType,
14
+ } from "./WorkspaceNotificationRuleService";
12
15
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
13
16
 
14
17
  export class Service extends DatabaseService<Model> {
@@ -30,6 +33,13 @@ export class Service extends DatabaseService<Model> {
30
33
  displayColor?: Color | undefined;
31
34
  userId?: ObjectID | undefined;
32
35
  postedAt?: Date | undefined;
36
+ workspaceNotification?:
37
+ | {
38
+ notifyUserId?: ObjectID | undefined;
39
+ sendWorkspaceNotification: boolean;
40
+ appendMessageBlocks?: Array<MessageBlocksByWorkspaceType> | undefined;
41
+ }
42
+ | undefined;
33
43
  }): Promise<void> {
34
44
  try {
35
45
  if (!data.alertEpisodeId) {
@@ -83,12 +93,52 @@ export class Service extends DatabaseService<Model> {
83
93
  isRoot: true,
84
94
  },
85
95
  });
96
+
97
+ try {
98
+ if (
99
+ data.workspaceNotification &&
100
+ data.workspaceNotification?.sendWorkspaceNotification
101
+ ) {
102
+ await this.sendWorkspaceNotification({
103
+ projectId: data.projectId,
104
+ alertEpisodeId: data.alertEpisodeId,
105
+ feedInfoInMarkdown: data.feedInfoInMarkdown,
106
+ workspaceNotification: data.workspaceNotification,
107
+ });
108
+ }
109
+ } catch (e) {
110
+ logger.error("Error in sending notification to slack and teams");
111
+ logger.error(e);
112
+ }
86
113
  } catch (error) {
87
114
  logger.error("AlertEpisodeFeedService.createAlertEpisodeFeedItem");
88
115
  logger.error(error);
89
116
  // we dont want to throw the error here, as this is a non-critical operation
90
117
  }
91
118
  }
119
+
120
+ @CaptureSpan()
121
+ public async sendWorkspaceNotification(data: {
122
+ projectId: ObjectID;
123
+ alertEpisodeId: ObjectID;
124
+ feedInfoInMarkdown: string;
125
+ workspaceNotification: {
126
+ notifyUserId?: ObjectID | undefined;
127
+ sendWorkspaceNotification: boolean;
128
+ appendMessageBlocks?: Array<MessageBlocksByWorkspaceType> | undefined;
129
+ };
130
+ }): Promise<void> {
131
+ return await WorkspaceNotificationRuleService.sendWorkspaceMarkdownNotification(
132
+ {
133
+ projectId: data.projectId,
134
+ notificationFor: {
135
+ alertEpisodeId: data.alertEpisodeId,
136
+ },
137
+ feedInfoInMarkdown: data.feedInfoInMarkdown,
138
+ workspaceNotification: data.workspaceNotification,
139
+ },
140
+ );
141
+ }
92
142
  }
93
143
 
94
144
  export default new Service();