@oneuptime/common 7.0.4039 → 7.0.4064

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 (92) hide show
  1. package/Models/DatabaseModels/Index.ts +9 -1
  2. package/Models/DatabaseModels/OnCallDutyPolicy.ts +20 -0
  3. package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +527 -0
  4. package/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.ts +426 -0
  5. package/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.ts +425 -0
  6. package/Server/API/SlackAPI.ts +14 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1744804990712-MigrationName.ts +17 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1744809770336-MigrationName.ts +173 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  10. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +71 -2
  11. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +14 -0
  12. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +69 -2
  13. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +77 -2
  14. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +1 -1
  15. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +1 -1
  16. package/Server/Services/OnCallDutyPolicyFeedService.ts +156 -0
  17. package/Server/Services/OnCallDutyPolicyOwnerTeamService.ts +181 -0
  18. package/Server/Services/OnCallDutyPolicyOwnerUserService.ts +174 -0
  19. package/Server/Services/OnCallDutyPolicyScheduleService.ts +101 -9
  20. package/Server/Services/OnCallDutyPolicyService.ts +219 -1
  21. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +184 -1
  22. package/Server/Services/WorkspaceNotificationRuleService.ts +93 -0
  23. package/Server/Utils/StartServer.ts +5 -2
  24. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +3 -0
  25. package/Server/Utils/Workspace/Slack/Actions/OnCallDutyPolicy.ts +48 -0
  26. package/Server/Utils/Workspace/Slack/Messages/OnCallDutyPolicy.ts +62 -0
  27. package/Server/Utils/Workspace/WorkspaceMessages/OnCallDutyPolicy.ts +75 -0
  28. package/Types/Permission.ts +112 -7
  29. package/Types/Workspace/NotificationRules/EventType.ts +1 -0
  30. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +5 -0
  31. package/UI/webpack-middleware.js +65 -0
  32. package/build/dist/Models/DatabaseModels/Index.js +8 -0
  33. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  34. package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js +20 -0
  35. package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js.map +1 -1
  36. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +549 -0
  37. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -0
  38. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.js +442 -0
  39. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.js.map +1 -0
  40. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.js +441 -0
  41. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.js.map +1 -0
  42. package/build/dist/Server/API/SlackAPI.js +11 -0
  43. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  44. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1744804990712-MigrationName.js +12 -0
  45. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1744804990712-MigrationName.js.map +1 -0
  46. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1744809770336-MigrationName.js +66 -0
  47. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1744809770336-MigrationName.js.map +1 -0
  48. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  49. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  50. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +52 -3
  51. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  52. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +12 -0
  53. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  54. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +52 -3
  55. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  56. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +63 -3
  57. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  58. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +1 -1
  59. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  60. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +1 -1
  61. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  62. package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js +119 -0
  63. package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js.map +1 -0
  64. package/build/dist/Server/Services/OnCallDutyPolicyOwnerTeamService.js +161 -0
  65. package/build/dist/Server/Services/OnCallDutyPolicyOwnerTeamService.js.map +1 -0
  66. package/build/dist/Server/Services/OnCallDutyPolicyOwnerUserService.js +154 -0
  67. package/build/dist/Server/Services/OnCallDutyPolicyOwnerUserService.js.map +1 -0
  68. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +87 -20
  69. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  70. package/build/dist/Server/Services/OnCallDutyPolicyService.js +174 -2
  71. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  72. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +122 -0
  73. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  74. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +71 -0
  75. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  76. package/build/dist/Server/Utils/StartServer.js +5 -2
  77. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  78. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +2 -0
  79. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  80. package/build/dist/Server/Utils/Workspace/Slack/Actions/OnCallDutyPolicy.js +50 -0
  81. package/build/dist/Server/Utils/Workspace/Slack/Actions/OnCallDutyPolicy.js.map +1 -0
  82. package/build/dist/Server/Utils/Workspace/Slack/Messages/OnCallDutyPolicy.js +52 -0
  83. package/build/dist/Server/Utils/Workspace/Slack/Messages/OnCallDutyPolicy.js.map +1 -0
  84. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/OnCallDutyPolicy.js +69 -0
  85. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/OnCallDutyPolicy.js.map +1 -0
  86. package/build/dist/Types/Permission.js +95 -7
  87. package/build/dist/Types/Permission.js.map +1 -1
  88. package/build/dist/Types/Workspace/NotificationRules/EventType.js +1 -0
  89. package/build/dist/Types/Workspace/NotificationRules/EventType.js.map +1 -1
  90. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +4 -0
  91. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  92. package/package.json +2 -2
@@ -14,6 +14,10 @@ import { CallRequestMessage } from "../../Types/Call/CallRequest";
14
14
  import DeleteBy from "../Types/Database/DeleteBy";
15
15
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
16
16
  import OnCallDutyPolicyScheduleService from "./OnCallDutyPolicyScheduleService";
17
+ import OnCallDutyPolicySchedule from "../../Models/DatabaseModels/OnCallDutyPolicySchedule";
18
+ import OnCallDutyPolicyFeedService from "./OnCallDutyPolicyFeedService";
19
+ import { OnCallDutyPolicyFeedEventType } from "../../Models/DatabaseModels/OnCallDutyPolicyFeed";
20
+ import { Gray500, Red500 } from "../../Types/BrandColors";
17
21
 
18
22
  export class Service extends DatabaseService<Model> {
19
23
  public constructor() {
@@ -47,6 +51,7 @@ export class Service extends DatabaseService<Model> {
47
51
  name: true,
48
52
  _id: true,
49
53
  },
54
+ createdByUserId: true,
50
55
  },
51
56
  props: {
52
57
  isRoot: true,
@@ -97,7 +102,7 @@ export class Service extends DatabaseService<Model> {
97
102
  "No order provided",
98
103
  reason: "You are currently on roster for schedule " + scheduleName,
99
104
  onCallPolicyViewLink: (
100
- await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(
105
+ await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(
101
106
  createdModel!.projectId!,
102
107
  createdModel.onCallDutyPolicy!.id!,
103
108
  )
@@ -133,6 +138,36 @@ export class Service extends DatabaseService<Model> {
133
138
  NotificationSettingEventType.SEND_WHEN_USER_IS_ADDED_TO_ON_CALL_POLICY,
134
139
  });
135
140
 
141
+ // add workspace message.
142
+
143
+ const onCallDutyPolicyId: ObjectID | undefined | null =
144
+ createdModel.onCallDutyPolicy!.id;
145
+ const projectId: ObjectID | undefined = createdModel.projectId;
146
+
147
+ const createdByUserId: ObjectID | undefined | null =
148
+ createdModel.createdByUserId;
149
+
150
+ const onCallSchedule: OnCallDutyPolicySchedule | undefined =
151
+ createdModel.onCallDutyPolicySchedule;
152
+ const onCallDutyPolicyName: string | null =
153
+ createdModel.onCallDutyPolicy?.name || "";
154
+
155
+ if (onCallDutyPolicyId) {
156
+ await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
157
+ onCallDutyPolicyId: onCallDutyPolicyId,
158
+ projectId: projectId!,
159
+ onCallDutyPolicyFeedEventType:
160
+ OnCallDutyPolicyFeedEventType.OnCallDutyScheduleAdded,
161
+ displayColor: Gray500,
162
+ feedInfoInMarkdown: `📅 Added on-call schedule **${onCallSchedule?.name || ""}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId!, onCallDutyPolicyId!)).toString()}) escalation rule **${createdModel.onCallDutyPolicyEscalationRule?.name}** with order **${createdModel.onCallDutyPolicyEscalationRule?.order}**.`,
163
+ userId: createdByUserId || undefined,
164
+ workspaceNotification: {
165
+ sendWorkspaceNotification: true,
166
+ notifyUserId: createdByUserId || undefined,
167
+ },
168
+ });
169
+ }
170
+
136
171
  return createdItem;
137
172
  }
138
173
 
@@ -165,6 +200,40 @@ export class Service extends DatabaseService<Model> {
165
200
  skip: 0,
166
201
  });
167
202
 
203
+ const deleteByUserId: ObjectID | undefined =
204
+ deleteBy.deletedByUser?.id || deleteBy.props.userId;
205
+ for (const item of itemsToFetchBeforeDelete) {
206
+ const onCallDutyPolicyId: ObjectID | undefined =
207
+ item.onCallDutyPolicy!.id!;
208
+ const projectId: ObjectID | undefined = item.projectId;
209
+
210
+ if (onCallDutyPolicyId && projectId) {
211
+ const onCallDutyPolicyName: string | null =
212
+ item.onCallDutyPolicy?.name || "No name provided";
213
+
214
+ const onCallSchedule: OnCallDutyPolicySchedule | undefined =
215
+ item.onCallDutyPolicySchedule;
216
+
217
+ if (!onCallSchedule) {
218
+ continue;
219
+ }
220
+
221
+ await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
222
+ onCallDutyPolicyId: onCallDutyPolicyId,
223
+ projectId: projectId,
224
+ onCallDutyPolicyFeedEventType:
225
+ OnCallDutyPolicyFeedEventType.OwnerTeamRemoved,
226
+ displayColor: Red500,
227
+ feedInfoInMarkdown: `📅 Removed on-call schedule **${onCallSchedule.name}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId!, onCallDutyPolicyId!)).toString()}) escalation rule ${item.onCallDutyPolicyEscalationRule?.name} with order ${item.onCallDutyPolicyEscalationRule?.order}.`,
228
+ userId: deleteByUserId || undefined,
229
+ workspaceNotification: {
230
+ sendWorkspaceNotification: true,
231
+ notifyUserId: deleteByUserId || undefined,
232
+ },
233
+ });
234
+ }
235
+ }
236
+
168
237
  return {
169
238
  deleteBy,
170
239
  carryForward: {
@@ -209,7 +278,7 @@ export class Service extends DatabaseService<Model> {
209
278
  "No order provided",
210
279
  reason: `You have been removed from the on-call duty policy escalation rule for schedule ${scheduleName}.`,
211
280
  onCallPolicyViewLink: (
212
- await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(
281
+ await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(
213
282
  deletedItem!.projectId!,
214
283
  deletedItem.onCallDutyPolicy!.id!,
215
284
  )
@@ -543,6 +543,9 @@ export class Service extends DatabaseService<Model> {
543
543
  teamInRule.onCallDutyPolicyId = onCallDutyPolicyId;
544
544
  teamInRule.onCallDutyPolicyEscalationRuleId = escalationRuleId;
545
545
  teamInRule.teamId = teamId;
546
+ if (props.userId) {
547
+ teamInRule.createdByUserId = props.userId;
548
+ }
546
549
 
547
550
  await OnCallDutyPolicyEscalationRuleTeamService.create({
548
551
  data: teamInRule,
@@ -565,6 +568,10 @@ export class Service extends DatabaseService<Model> {
565
568
  scheduleInRule.onCallDutyPolicyEscalationRuleId = escalationRuleId;
566
569
  scheduleInRule.onCallDutyPolicyScheduleId = onCallScheduleId;
567
570
 
571
+ if (props.userId) {
572
+ scheduleInRule.createdByUserId = props.userId;
573
+ }
574
+
568
575
  await OnCallDutyPolicyEscalationRuleScheduleService.create({
569
576
  data: scheduleInRule,
570
577
  props,
@@ -586,6 +593,10 @@ export class Service extends DatabaseService<Model> {
586
593
  userInRule.onCallDutyPolicyEscalationRuleId = escalationRuleId;
587
594
  userInRule.userId = userId;
588
595
 
596
+ if (props.userId) {
597
+ userInRule.createdByUserId = props.userId;
598
+ }
599
+
589
600
  await OnCallDutyPolicyEscalationRuleUserService.create({
590
601
  data: userInRule,
591
602
  props,
@@ -690,6 +701,7 @@ export class Service extends DatabaseService<Model> {
690
701
  limit: LIMIT_PER_PROJECT,
691
702
  skip: 0,
692
703
  props: {
704
+ userId: deleteBy.props.userId,
693
705
  isRoot: true,
694
706
  },
695
707
  });
@@ -703,6 +715,7 @@ export class Service extends DatabaseService<Model> {
703
715
  limit: LIMIT_PER_PROJECT,
704
716
  skip: 0,
705
717
  props: {
718
+ userId: deleteBy.props.userId,
706
719
  isRoot: true,
707
720
  },
708
721
  });
@@ -716,6 +729,7 @@ export class Service extends DatabaseService<Model> {
716
729
  limit: LIMIT_PER_PROJECT,
717
730
  skip: 0,
718
731
  props: {
732
+ userId: deleteBy.props.userId,
719
733
  isRoot: true,
720
734
  },
721
735
  });
@@ -15,6 +15,10 @@ import DeleteBy from "../Types/Database/DeleteBy";
15
15
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
16
16
  import TeamMemberService from "./TeamMemberService";
17
17
  import User from "../../Models/DatabaseModels/User";
18
+ import OnCallDutyPolicyFeedService from "./OnCallDutyPolicyFeedService";
19
+ import { OnCallDutyPolicyFeedEventType } from "../../Models/DatabaseModels/OnCallDutyPolicyFeed";
20
+ import { Gray500, Red500 } from "../../Types/BrandColors";
21
+ import Team from "../../Models/DatabaseModels/Team";
18
22
 
19
23
  export class Service extends DatabaseService<Model> {
20
24
  public constructor() {
@@ -48,6 +52,7 @@ export class Service extends DatabaseService<Model> {
48
52
  name: true,
49
53
  _id: true,
50
54
  },
55
+ createdByUserId: true,
51
56
  },
52
57
  props: {
53
58
  isRoot: true,
@@ -94,7 +99,7 @@ export class Service extends DatabaseService<Model> {
94
99
  "You have been added to the on-call duty policy escalation rule because you are a member of the team " +
95
100
  temaName,
96
101
  onCallPolicyViewLink: (
97
- await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(
102
+ await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(
98
103
  createdModel!.projectId!,
99
104
  createdModel.onCallDutyPolicy!.id!,
100
105
  )
@@ -131,6 +136,34 @@ export class Service extends DatabaseService<Model> {
131
136
  });
132
137
  }
133
138
 
139
+ // add workspace message.
140
+
141
+ const onCallDutyPolicyId: ObjectID | undefined | null =
142
+ createdModel.onCallDutyPolicy!.id;
143
+ const projectId: ObjectID | undefined = createdModel.projectId;
144
+
145
+ const createdByUserId: ObjectID | undefined | null =
146
+ createdModel.createdByUserId;
147
+
148
+ const team: Team | undefined = createdModel.team;
149
+ const onCallDutyPolicyName: string | null =
150
+ createdModel.onCallDutyPolicy?.name || "";
151
+
152
+ if (onCallDutyPolicyId) {
153
+ await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
154
+ onCallDutyPolicyId: onCallDutyPolicyId,
155
+ projectId: projectId!,
156
+ onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.TeamAdded,
157
+ displayColor: Gray500,
158
+ feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Added team **${team?.name || ""}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId!, onCallDutyPolicyId!)).toString()}) escalation rule **${createdModel.onCallDutyPolicyEscalationRule?.name}** with order **${createdModel.onCallDutyPolicyEscalationRule?.order}**.`,
159
+ userId: createdByUserId || undefined,
160
+ workspaceNotification: {
161
+ sendWorkspaceNotification: true,
162
+ notifyUserId: createdByUserId || undefined,
163
+ },
164
+ });
165
+ }
166
+
134
167
  return createdItem;
135
168
  }
136
169
 
@@ -163,6 +196,40 @@ export class Service extends DatabaseService<Model> {
163
196
  skip: 0,
164
197
  });
165
198
 
199
+ const deleteByUserId: ObjectID | undefined =
200
+ deleteBy.deletedByUser?.id || deleteBy.props.userId;
201
+
202
+ for (const item of itemsToFetchBeforeDelete) {
203
+ const onCallDutyPolicyId: ObjectID | undefined =
204
+ item.onCallDutyPolicy!.id!;
205
+ const projectId: ObjectID | undefined = item.projectId;
206
+
207
+ if (onCallDutyPolicyId && projectId) {
208
+ const onCallDutyPolicyName: string | null =
209
+ item.onCallDutyPolicy?.name || "No name provided";
210
+
211
+ const team: Team | undefined = item.team;
212
+
213
+ if (!team) {
214
+ continue;
215
+ }
216
+
217
+ await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
218
+ onCallDutyPolicyId: onCallDutyPolicyId,
219
+ projectId: projectId,
220
+ onCallDutyPolicyFeedEventType:
221
+ OnCallDutyPolicyFeedEventType.OwnerTeamRemoved,
222
+ displayColor: Red500,
223
+ feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Removed team **${team.name}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId!, onCallDutyPolicyId!)).toString()}) and escalation rule ${item.onCallDutyPolicyEscalationRule?.name} with order ${item.onCallDutyPolicyEscalationRule?.order}.`,
224
+ userId: deleteByUserId || undefined,
225
+ workspaceNotification: {
226
+ sendWorkspaceNotification: true,
227
+ notifyUserId: deleteByUserId || undefined,
228
+ },
229
+ });
230
+ }
231
+ }
232
+
166
233
  return {
167
234
  deleteBy,
168
235
  carryForward: {
@@ -202,7 +269,7 @@ export class Service extends DatabaseService<Model> {
202
269
  "No order provided",
203
270
  reason: `You have been removed from the on-call duty policy escalation rule for team ${teamName}.`,
204
271
  onCallPolicyViewLink: (
205
- await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(
272
+ await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(
206
273
  deletedItem!.projectId!,
207
274
  deletedItem.onCallDutyPolicy!.id!,
208
275
  )
@@ -13,6 +13,11 @@ import NotificationSettingEventType from "../../Types/NotificationSetting/Notifi
13
13
  import { CallRequestMessage } from "../../Types/Call/CallRequest";
14
14
  import DeleteBy from "../Types/Database/DeleteBy";
15
15
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
16
+ import OnCallDutyPolicyFeedService from "./OnCallDutyPolicyFeedService";
17
+ import { OnCallDutyPolicyFeedEventType } from "../../Models/DatabaseModels/OnCallDutyPolicyFeed";
18
+ import { Gray500, Red500 } from "../../Types/BrandColors";
19
+ import UserService from "./UserService";
20
+ import User from "../../Models/DatabaseModels/User";
16
21
 
17
22
  export class Service extends DatabaseService<Model> {
18
23
  public constructor() {
@@ -46,6 +51,7 @@ export class Service extends DatabaseService<Model> {
46
51
  name: true,
47
52
  _id: true,
48
53
  },
54
+ createdByUserId: true,
49
55
  },
50
56
  props: {
51
57
  isRoot: true,
@@ -75,7 +81,7 @@ export class Service extends DatabaseService<Model> {
75
81
  "No order provided",
76
82
  reason: "You have been added to the on-call duty policy escalation rule.",
77
83
  onCallPolicyViewLink: (
78
- await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(
84
+ await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(
79
85
  createdModel!.projectId!,
80
86
  createdModel.onCallDutyPolicy!.id!,
81
87
  )
@@ -111,6 +117,32 @@ export class Service extends DatabaseService<Model> {
111
117
  NotificationSettingEventType.SEND_WHEN_USER_IS_ADDED_TO_ON_CALL_POLICY,
112
118
  });
113
119
 
120
+ // add workspace message.
121
+
122
+ const onCallDutyPolicyId: ObjectID | undefined | null =
123
+ createdModel.onCallDutyPolicy!.id;
124
+ const projectId: ObjectID | undefined = createdModel.projectId;
125
+
126
+ if (onCallDutyPolicyId) {
127
+ await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
128
+ onCallDutyPolicyId: onCallDutyPolicyId,
129
+ projectId: projectId!,
130
+ onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.UserAdded,
131
+ displayColor: Gray500,
132
+ feedInfoInMarkdown: `👨🏻‍💻 Added **${await UserService.getUserMarkdownString(
133
+ {
134
+ userId: createdModel.user!.id!,
135
+ projectId: projectId!,
136
+ },
137
+ )}** to the [On-Call Policy ${createdModel.onCallDutyPolicy?.name}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId!, onCallDutyPolicyId!)).toString()}) escalation rule **${createdModel.onCallDutyPolicyEscalationRule?.name}** with order **${createdModel.onCallDutyPolicyEscalationRule?.order}**.`,
138
+ userId: createdModel.createdByUserId! || undefined,
139
+ workspaceNotification: {
140
+ sendWorkspaceNotification: true,
141
+ notifyUserId: createdModel.createdByUserId! || undefined,
142
+ },
143
+ });
144
+ }
145
+
114
146
  return createdItem;
115
147
  }
116
148
 
@@ -137,11 +169,54 @@ export class Service extends DatabaseService<Model> {
137
169
  name: true,
138
170
  _id: true,
139
171
  },
172
+ createdByUserId: true,
140
173
  },
141
174
  limit: LIMIT_PER_PROJECT,
142
175
  skip: 0,
143
176
  });
144
177
 
178
+ const deleteByUserId: ObjectID | undefined =
179
+ deleteBy.deletedByUser?.id || deleteBy.props.userId;
180
+
181
+ for (const item of itemsToFetchBeforeDelete) {
182
+ const onCallDutyPolicyId: ObjectID | undefined =
183
+ item.onCallDutyPolicy!.id!;
184
+ const projectId: ObjectID | undefined = item.projectId;
185
+ const userId: ObjectID | undefined = item.user!.id!;
186
+
187
+ if (onCallDutyPolicyId && userId && projectId) {
188
+ const user: User | null = await UserService.findOneById({
189
+ id: userId,
190
+ select: {
191
+ name: true,
192
+ email: true,
193
+ },
194
+ props: {
195
+ isRoot: true,
196
+ },
197
+ });
198
+
199
+ const onCallDutyPolicyName: string | null =
200
+ item.onCallDutyPolicy?.name || "No name provided";
201
+
202
+ if (user && user.name) {
203
+ await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
204
+ onCallDutyPolicyId: onCallDutyPolicyId,
205
+ projectId: projectId,
206
+ onCallDutyPolicyFeedEventType:
207
+ OnCallDutyPolicyFeedEventType.OwnerUserRemoved,
208
+ displayColor: Red500,
209
+ feedInfoInMarkdown: `👨🏻‍💻 Removed **${user.name.toString()}** (${user.email?.toString()}) from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId!, onCallDutyPolicyId!)).toString()}) for escalation rule ${item.onCallDutyPolicyEscalationRule?.name} with order ${item.onCallDutyPolicyEscalationRule?.order}.`,
210
+ userId: deleteByUserId || undefined,
211
+ workspaceNotification: {
212
+ sendWorkspaceNotification: true,
213
+ notifyUserId: userId || undefined,
214
+ },
215
+ });
216
+ }
217
+ }
218
+ }
219
+
145
220
  return {
146
221
  deleteBy,
147
222
  carryForward: {
@@ -176,7 +251,7 @@ export class Service extends DatabaseService<Model> {
176
251
  reason:
177
252
  "You have been removed from the on-call duty policy escalation rule.",
178
253
  onCallPolicyViewLink: (
179
- await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(
254
+ await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(
180
255
  deletedItem!.projectId!,
181
256
  deletedItem.onCallDutyPolicy!.id!,
182
257
  )
@@ -310,7 +310,7 @@ export class Service extends DatabaseService<Model> {
310
310
 
311
311
  const feedInfoInMarkdown: string = `**${this.getEmojiByStatus(onCalldutyPolicyExecutionLog.status)} On Call Policy Status Updated for ${incidentOrAlertLink}:**
312
312
 
313
- On-call policy **[${onCallPolicy.name?.toString()}](${(await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(onCallPolicy.projectId!, onCallPolicy.id!)).toString()})** status updated to **${onCalldutyPolicyExecutionLog.status}**`;
313
+ On-call policy **[${onCallPolicy.name?.toString()}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(onCallPolicy.projectId!, onCallPolicy.id!)).toString()})** status updated to **${onCalldutyPolicyExecutionLog.status}**`;
314
314
 
315
315
  if (onCalldutyPolicyExecutionLog.triggeredByIncidentId) {
316
316
  await IncidentFeedService.createIncidentFeedItem({
@@ -179,7 +179,7 @@ export class Service extends DatabaseService<Model> {
179
179
  },
180
180
  )}**
181
181
 
182
- The on-call policy **[${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.name}](${(await OnCallDutyPolicyService.getOnCallPolicyLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.id!)).toString()})** has been triggered. The escalation rule **${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicyEscalationRule?.name}** ${onCallDutyPolicyExecutionLogTimeline.onCallDutySchedule?.name ? String(" and schedule **" + onCallDutyPolicyExecutionLogTimeline.onCallDutySchedule?.name + "**") : ""} were applied. ${await UserService.getUserMarkdownString(
182
+ The on-call policy **[${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.name}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(onCallDutyPolicyExecutionLogTimeline.projectId!, onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.id!)).toString()})** has been triggered. The escalation rule **${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicyEscalationRule?.name}** ${onCallDutyPolicyExecutionLogTimeline.onCallDutySchedule?.name ? String(" and schedule **" + onCallDutyPolicyExecutionLogTimeline.onCallDutySchedule?.name + "**") : ""} were applied. ${await UserService.getUserMarkdownString(
183
183
  {
184
184
  userId: onCallDutyPolicyExecutionLogTimeline.alertSentToUserId!,
185
185
  projectId: onCallDutyPolicyExecutionLogTimeline.projectId!,
@@ -0,0 +1,156 @@
1
+ import { Blue500 } from "../../Types/BrandColors";
2
+ import Color from "../../Types/Color";
3
+ import OneUptimeDate from "../../Types/Date";
4
+ import BadDataException from "../../Types/Exception/BadDataException";
5
+ import ObjectID from "../../Types/ObjectID";
6
+ import { IsBillingEnabled } from "../EnvironmentConfig";
7
+ import logger from "../Utils/Logger";
8
+ import DatabaseService from "./DatabaseService";
9
+ import OnCallDutyPolicyFeed, {
10
+ OnCallDutyPolicyFeedEventType,
11
+ } from "Common/Models/DatabaseModels/OnCallDutyPolicyFeed";
12
+ import WorkspaceNotificationRuleService, {
13
+ MessageBlocksByWorkspaceType,
14
+ } from "./WorkspaceNotificationRuleService";
15
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
16
+
17
+ export class Service extends DatabaseService<OnCallDutyPolicyFeed> {
18
+ public constructor() {
19
+ super(OnCallDutyPolicyFeed);
20
+
21
+ if (IsBillingEnabled) {
22
+ this.hardDeleteItemsOlderThanInDays("createdAt", 90);
23
+ }
24
+ }
25
+
26
+ @CaptureSpan()
27
+ public async createOnCallDutyPolicyFeedItem(data: {
28
+ onCallDutyPolicyId: ObjectID;
29
+ feedInfoInMarkdown: string;
30
+ onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType;
31
+ projectId: ObjectID;
32
+ moreInformationInMarkdown?: string | undefined;
33
+ displayColor?: Color | undefined;
34
+ userId?: ObjectID | undefined;
35
+ postedAt?: Date | undefined;
36
+ // send notifificatin to slack and teams. This is optional
37
+ workspaceNotification?:
38
+ | {
39
+ notifyUserId?: ObjectID | undefined; // this is oneuptime user id.
40
+ sendWorkspaceNotification: boolean;
41
+ appendMessageBlocks?: Array<MessageBlocksByWorkspaceType> | undefined;
42
+ }
43
+ | undefined;
44
+ }): Promise<void> {
45
+ try {
46
+ logger.debug(
47
+ "OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem",
48
+ );
49
+ logger.debug(data);
50
+
51
+ const onCallDutyPolicyFeed: OnCallDutyPolicyFeed =
52
+ new OnCallDutyPolicyFeed();
53
+
54
+ if (!data.onCallDutyPolicyId) {
55
+ throw new BadDataException("OnCallDutyPolicy ID is required");
56
+ }
57
+
58
+ if (!data.feedInfoInMarkdown) {
59
+ throw new BadDataException("Log in markdown is required");
60
+ }
61
+
62
+ if (!data.onCallDutyPolicyFeedEventType) {
63
+ throw new BadDataException("OnCallDutyPolicy log event is required");
64
+ }
65
+
66
+ if (!data.projectId) {
67
+ throw new BadDataException("Project ID is required");
68
+ }
69
+
70
+ if (!data.displayColor) {
71
+ data.displayColor = Blue500;
72
+ }
73
+
74
+ onCallDutyPolicyFeed.displayColor = data.displayColor;
75
+ onCallDutyPolicyFeed.onCallDutyPolicyId = data.onCallDutyPolicyId;
76
+ onCallDutyPolicyFeed.feedInfoInMarkdown = data.feedInfoInMarkdown;
77
+ onCallDutyPolicyFeed.onCallDutyPolicyFeedEventType =
78
+ data.onCallDutyPolicyFeedEventType;
79
+ onCallDutyPolicyFeed.projectId = data.projectId;
80
+
81
+ if (!data.postedAt) {
82
+ onCallDutyPolicyFeed.postedAt = OneUptimeDate.getCurrentDate();
83
+ }
84
+
85
+ if (data.userId) {
86
+ onCallDutyPolicyFeed.userId = data.userId;
87
+ }
88
+
89
+ if (data.moreInformationInMarkdown) {
90
+ onCallDutyPolicyFeed.moreInformationInMarkdown =
91
+ data.moreInformationInMarkdown;
92
+ }
93
+
94
+ const createdOnCallDutyPolicyFeed: OnCallDutyPolicyFeed =
95
+ await this.create({
96
+ data: onCallDutyPolicyFeed,
97
+ props: {
98
+ isRoot: true,
99
+ },
100
+ });
101
+
102
+ logger.debug("On Call Duty Policy Feed created");
103
+ logger.debug(createdOnCallDutyPolicyFeed);
104
+
105
+ try {
106
+ // send notification to slack and teams
107
+ if (
108
+ data.workspaceNotification &&
109
+ data.workspaceNotification?.sendWorkspaceNotification
110
+ ) {
111
+ await this.sendWorkspaceNotification({
112
+ projectId: data.projectId,
113
+ onCallDutyPolicyId: data.onCallDutyPolicyId,
114
+ feedInfoInMarkdown: data.feedInfoInMarkdown,
115
+ workspaceNotification: data.workspaceNotification,
116
+ });
117
+ }
118
+ } catch (e) {
119
+ logger.error("Error in sending notification to slack and teams");
120
+ logger.error(e);
121
+
122
+ // we dont throw this error as it is not a critical error
123
+ }
124
+ } catch (e) {
125
+ logger.error("Error in creating onCallDutyPolicy feed");
126
+ logger.error(e);
127
+
128
+ // we dont throw this error as it is not a critical error
129
+ }
130
+ }
131
+
132
+ @CaptureSpan()
133
+ public async sendWorkspaceNotification(data: {
134
+ projectId: ObjectID;
135
+ onCallDutyPolicyId: ObjectID;
136
+ feedInfoInMarkdown: string;
137
+ workspaceNotification: {
138
+ notifyUserId?: ObjectID | undefined; // this is oneuptime user id.
139
+ sendWorkspaceNotification: boolean;
140
+ appendMessageBlocks?: Array<MessageBlocksByWorkspaceType> | undefined;
141
+ };
142
+ }): Promise<void> {
143
+ return await WorkspaceNotificationRuleService.sendWorkspaceMarkdownNotification(
144
+ {
145
+ projectId: data.projectId,
146
+ notificationFor: {
147
+ onCallDutyPolicyId: data.onCallDutyPolicyId,
148
+ },
149
+ feedInfoInMarkdown: data.feedInfoInMarkdown,
150
+ workspaceNotification: data.workspaceNotification,
151
+ },
152
+ );
153
+ }
154
+ }
155
+
156
+ export default new Service();