@oneuptime/common 7.0.3480 → 7.0.3517

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 (209) hide show
  1. package/Models/DatabaseModels/{AlertLog.ts → AlertFeed.ts} +157 -33
  2. package/Models/DatabaseModels/Incident.ts +6 -1
  3. package/Models/DatabaseModels/{IncidentLog.ts → IncidentFeed.ts} +169 -37
  4. package/Models/DatabaseModels/Index.ts +6 -6
  5. package/Models/DatabaseModels/{ScheduledMaintenanceLog.ts → ScheduledMaintenanceFeed.ts} +155 -31
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/1736703138918-MigrationName.ts +29 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1736780194077-MigrationName.ts +137 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1736780194078-MigrationName.ts +16 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1736787495707-MigrationName.ts +29 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1736787985322-MigrationName.ts +83 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1736788706141-MigrationName.ts +39 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1736856662868-MigrationName.ts +27 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  14. package/Server/Services/AlertFeedService.ts +81 -0
  15. package/Server/Services/IncidentFeedService.ts +89 -0
  16. package/Server/Services/IncidentInternalNoteService.ts +28 -0
  17. package/Server/Services/IncidentOwnerTeamService.ts +112 -0
  18. package/Server/Services/IncidentOwnerUserService.ts +114 -0
  19. package/Server/Services/IncidentPublicNoteService.ts +26 -0
  20. package/Server/Services/IncidentService.ts +121 -0
  21. package/Server/Services/IncidentStateTimelineService.ts +43 -19
  22. package/Server/Services/Index.ts +6 -6
  23. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +116 -1
  24. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +169 -0
  25. package/Server/Services/ScheduledMaintenanceFeedService.ts +83 -0
  26. package/Server/Services/UserOnCallLogService.ts +2 -2
  27. package/Tests/Types/Database/ColumnLength.test.ts +1 -1
  28. package/Types/Database/ColumnLength.ts +1 -1
  29. package/Types/Database/LimitMax.ts +1 -1
  30. package/Types/Icon/IconProp.ts +1 -0
  31. package/Types/Permission.ts +32 -32
  32. package/UI/Components/CategoryCheckbox/Index.tsx +1 -1
  33. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +3 -3
  34. package/UI/Components/ErrorMessage/ErrorMessage.tsx +2 -2
  35. package/UI/Components/Feed/Feed.tsx +31 -0
  36. package/UI/Components/Feed/FeedItem.tsx +176 -0
  37. package/UI/Components/Filters/FilterViewer.tsx +1 -1
  38. package/UI/Components/Filters/FiltersForm.tsx +1 -1
  39. package/UI/Components/FormModal/BasicFormModal.tsx +1 -1
  40. package/UI/Components/Forms/BasicForm.tsx +1 -1
  41. package/UI/Components/Icon/Icon.tsx +16 -0
  42. package/UI/Components/InfoCard/InfoCard.tsx +1 -3
  43. package/UI/Components/List/List.tsx +2 -2
  44. package/UI/Components/LogsViewer/LogsViewer.tsx +1 -1
  45. package/UI/Components/ModelDetail/ModelDetail.tsx +1 -1
  46. package/UI/Components/ModelList/ModelList.tsx +2 -2
  47. package/UI/Components/ModelProgress/ModelProgress.tsx +1 -1
  48. package/UI/Components/ModelTable/BaseModelTable.tsx +3 -3
  49. package/UI/Components/MonitorGraphs/Uptime.tsx +1 -1
  50. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +5 -2
  51. package/UI/Components/Page/Page.tsx +1 -1
  52. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +107 -0
  53. package/UI/Components/ProgressButtons/ProgressButtons.tsx +88 -0
  54. package/UI/Components/QR/QR.tsx +1 -1
  55. package/UI/Components/Table/Table.tsx +2 -2
  56. package/UI/Components/Workflow/ArgumentsForm.tsx +1 -1
  57. package/UI/Components/Workflow/ComponentArgumentsViewer.tsx +1 -1
  58. package/UI/Components/Workflow/ComponentPortViewer.tsx +1 -1
  59. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +1 -1
  60. package/UI/Components/Workflow/ComponentValuePickerModal.tsx +3 -3
  61. package/UI/Components/Workflow/ComponentsModal.tsx +1 -1
  62. package/UI/Components/Workflow/DocumentationViewer.tsx +1 -1
  63. package/UI/Components/Workflow/RunForm.tsx +1 -1
  64. package/UI/Components/Workflow/RunModal.tsx +1 -1
  65. package/UI/Utils/User.ts +1 -1
  66. package/UI/index.d.ts +4 -0
  67. package/build/dist/Models/DatabaseModels/{AlertLog.js → AlertFeed.js} +184 -57
  68. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -0
  69. package/build/dist/Models/DatabaseModels/Incident.js +6 -1
  70. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  71. package/build/dist/Models/DatabaseModels/{IncidentLog.js → IncidentFeed.js} +192 -57
  72. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -0
  73. package/build/dist/Models/DatabaseModels/Index.js +6 -6
  74. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  75. package/build/dist/Models/DatabaseModels/{ScheduledMaintenanceLog.js → ScheduledMaintenanceFeed.js} +182 -55
  76. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceFeed.js.map +1 -0
  77. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736703138918-MigrationName.js +16 -0
  78. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736703138918-MigrationName.js.map +1 -0
  79. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736780194077-MigrationName.js +54 -0
  80. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736780194077-MigrationName.js.map +1 -0
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736780194078-MigrationName.js +15 -0
  82. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736780194078-MigrationName.js.map +1 -0
  83. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736787495707-MigrationName.js +16 -0
  84. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736787495707-MigrationName.js.map +1 -0
  85. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736787985322-MigrationName.js +34 -0
  86. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736787985322-MigrationName.js.map +1 -0
  87. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736788706141-MigrationName.js +22 -0
  88. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736788706141-MigrationName.js.map +1 -0
  89. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736856662868-MigrationName.js +16 -0
  90. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1736856662868-MigrationName.js.map +1 -0
  91. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  92. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  93. package/build/dist/Server/Services/AlertFeedService.js +54 -0
  94. package/build/dist/Server/Services/AlertFeedService.js.map +1 -0
  95. package/build/dist/Server/Services/IncidentFeedService.js +60 -0
  96. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -0
  97. package/build/dist/Server/Services/IncidentInternalNoteService.js +19 -0
  98. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  99. package/build/dist/Server/Services/IncidentOwnerTeamService.js +86 -0
  100. package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
  101. package/build/dist/Server/Services/IncidentOwnerUserService.js +89 -0
  102. package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
  103. package/build/dist/Server/Services/IncidentPublicNoteService.js +19 -0
  104. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  105. package/build/dist/Server/Services/IncidentService.js +108 -4
  106. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  107. package/build/dist/Server/Services/IncidentStateTimelineService.js +37 -15
  108. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  109. package/build/dist/Server/Services/Index.js +6 -6
  110. package/build/dist/Server/Services/Index.js.map +1 -1
  111. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +93 -0
  112. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  113. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +129 -0
  114. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  115. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js +57 -0
  116. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js.map +1 -0
  117. package/build/dist/Server/Services/UserOnCallLogService.js +2 -2
  118. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  119. package/build/dist/Tests/Types/Database/ColumnLength.test.js +1 -1
  120. package/build/dist/Tests/Types/Database/ColumnLength.test.js.map +1 -1
  121. package/build/dist/Types/Database/ColumnLength.js +1 -1
  122. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  123. package/build/dist/Types/Database/LimitMax.js +1 -1
  124. package/build/dist/Types/Database/LimitMax.js.map +1 -1
  125. package/build/dist/Types/Icon/IconProp.js +1 -0
  126. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  127. package/build/dist/Types/Permission.js +32 -32
  128. package/build/dist/Types/Permission.js.map +1 -1
  129. package/build/dist/UI/Components/CategoryCheckbox/Index.js +1 -1
  130. package/build/dist/UI/Components/CategoryCheckbox/Index.js.map +1 -1
  131. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +3 -3
  132. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  133. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
  134. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
  135. package/build/dist/UI/Components/Feed/Feed.js +14 -0
  136. package/build/dist/UI/Components/Feed/Feed.js.map +1 -0
  137. package/build/dist/UI/Components/Feed/FeedItem.js +67 -0
  138. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -0
  139. package/build/dist/UI/Components/Filters/FilterViewer.js +1 -1
  140. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  141. package/build/dist/UI/Components/Filters/FiltersForm.js +1 -1
  142. package/build/dist/UI/Components/Filters/FiltersForm.js.map +1 -1
  143. package/build/dist/UI/Components/FormModal/BasicFormModal.js +1 -1
  144. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  145. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  146. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  147. package/build/dist/UI/Components/Icon/Icon.js +6 -0
  148. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  149. package/build/dist/UI/Components/InfoCard/InfoCard.js +1 -1
  150. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  151. package/build/dist/UI/Components/List/List.js +2 -2
  152. package/build/dist/UI/Components/List/List.js.map +1 -1
  153. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +1 -1
  154. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  155. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +1 -1
  156. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  157. package/build/dist/UI/Components/ModelList/ModelList.js +2 -2
  158. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  159. package/build/dist/UI/Components/ModelProgress/ModelProgress.js +1 -1
  160. package/build/dist/UI/Components/ModelProgress/ModelProgress.js.map +1 -1
  161. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +3 -3
  162. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  163. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  164. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  165. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +2 -2
  166. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  167. package/build/dist/UI/Components/Page/Page.js +1 -1
  168. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  169. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +26 -0
  170. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -0
  171. package/build/dist/UI/Components/ProgressButtons/ProgressButtons.js +36 -0
  172. package/build/dist/UI/Components/ProgressButtons/ProgressButtons.js.map +1 -0
  173. package/build/dist/UI/Components/QR/QR.js +1 -1
  174. package/build/dist/UI/Components/QR/QR.js.map +1 -1
  175. package/build/dist/UI/Components/Table/Table.js +2 -2
  176. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  177. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +1 -1
  178. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  179. package/build/dist/UI/Components/Workflow/ComponentArgumentsViewer.js +1 -1
  180. package/build/dist/UI/Components/Workflow/ComponentArgumentsViewer.js.map +1 -1
  181. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js +1 -1
  182. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js.map +1 -1
  183. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +1 -1
  184. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  185. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +3 -3
  186. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
  187. package/build/dist/UI/Components/Workflow/ComponentsModal.js +1 -1
  188. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  189. package/build/dist/UI/Components/Workflow/DocumentationViewer.js +1 -1
  190. package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
  191. package/build/dist/UI/Components/Workflow/RunForm.js +1 -1
  192. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  193. package/build/dist/UI/Components/Workflow/RunModal.js +1 -1
  194. package/build/dist/UI/Components/Workflow/RunModal.js.map +1 -1
  195. package/build/dist/UI/Utils/User.js +1 -1
  196. package/build/dist/UI/Utils/User.js.map +1 -1
  197. package/package.json +2 -2
  198. package/Server/Services/AlertLogService.ts +0 -10
  199. package/Server/Services/IncidentLogService.ts +0 -10
  200. package/Server/Services/ScheduledMaintenanceLogService.ts +0 -10
  201. package/build/dist/Models/DatabaseModels/AlertLog.js.map +0 -1
  202. package/build/dist/Models/DatabaseModels/IncidentLog.js.map +0 -1
  203. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLog.js.map +0 -1
  204. package/build/dist/Server/Services/AlertLogService.js +0 -9
  205. package/build/dist/Server/Services/AlertLogService.js.map +0 -1
  206. package/build/dist/Server/Services/IncidentLogService.js +0 -9
  207. package/build/dist/Server/Services/IncidentLogService.js.map +0 -1
  208. package/build/dist/Server/Services/ScheduledMaintenanceLogService.js +0 -9
  209. package/build/dist/Server/Services/ScheduledMaintenanceLogService.js.map +0 -1
@@ -20,6 +20,8 @@ import IncidentStateTimeline from "Common/Models/DatabaseModels/IncidentStateTim
20
20
  import User from "Common/Models/DatabaseModels/User";
21
21
  import { IsBillingEnabled } from "../EnvironmentConfig";
22
22
  import logger from "../Utils/Logger";
23
+ import IncidentFeedService from "./IncidentFeedService";
24
+ import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
23
25
 
24
26
  export class Service extends DatabaseService<IncidentStateTimeline> {
25
27
  public constructor() {
@@ -120,32 +122,17 @@ export class Service extends DatabaseService<IncidentStateTimeline> {
120
122
  )?.["publicNote"] as string | undefined;
121
123
 
122
124
  if (publicNote) {
123
- const incidentPublicNote: IncidentPublicNote = new IncidentPublicNote();
124
- incidentPublicNote.incidentId = createBy.data.incidentId;
125
- incidentPublicNote.note = publicNote;
126
- incidentPublicNote.postedAt = createBy.data.startsAt;
127
- incidentPublicNote.createdAt = createBy.data.startsAt;
128
- incidentPublicNote.projectId = createBy.data.projectId!;
129
- incidentPublicNote.shouldStatusPageSubscribersBeNotifiedOnNoteCreated =
130
- Boolean(createBy.data.shouldStatusPageSubscribersBeNotified);
131
-
132
125
  // mark status page subscribers as notified for this state change because we dont want to send duplicate (two) emails one for public note and one for state change.
133
- if (
134
- incidentPublicNote.shouldStatusPageSubscribersBeNotifiedOnNoteCreated
135
- ) {
126
+ if (createBy.data.shouldStatusPageSubscribersBeNotified) {
136
127
  createBy.data.isStatusPageSubscribersNotified = true;
137
128
  }
138
-
139
- await IncidentPublicNoteService.create({
140
- data: incidentPublicNote,
141
- props: createBy.props,
142
- });
143
129
  }
144
130
 
145
131
  return {
146
132
  createBy,
147
133
  carryForward: {
148
134
  lastIncidentStateTimelineId: lastIncidentStateTimeline?.id || null,
135
+ publicNote: publicNote,
149
136
  },
150
137
  };
151
138
  }
@@ -189,20 +176,39 @@ export class Service extends DatabaseService<IncidentStateTimeline> {
189
176
  // TODO: DELETE THIS WHEN WORKFLOW IS IMPLEMENMTED.
190
177
  // check if this is resolved state, and if it is then resolve all the monitors.
191
178
 
192
- const isResolvedState: IncidentState | null =
179
+ const incidentState: IncidentState | null =
193
180
  await IncidentStateService.findOneBy({
194
181
  query: {
195
182
  _id: createdItem.incidentStateId.toString()!,
196
- isResolvedState: true,
197
183
  },
198
184
  props: {
199
185
  isRoot: true,
200
186
  },
201
187
  select: {
202
188
  _id: true,
189
+ isResolvedState: true,
190
+ isAcknowledgedState: true,
191
+ isCreatedState: true,
192
+ color: true,
193
+ name: true,
203
194
  },
204
195
  });
205
196
 
197
+ const stateName: string = incidentState?.name || "";
198
+
199
+ await IncidentFeedService.createIncidentFeed({
200
+ incidentId: createdItem.incidentId!,
201
+ projectId: createdItem.projectId!,
202
+ incidentFeedEventType: IncidentFeedEventType.IncidentStateChanged,
203
+ displayColor: incidentState?.color,
204
+ feedInfoInMarkdown: "**Incident State** changed to **" + stateName + "**",
205
+ moreInformationInMarkdown: `**Cause:**
206
+ ${createdItem.rootCause}`,
207
+ userId: createdItem.createdByUserId || onCreate.createBy.props.userId,
208
+ });
209
+
210
+ const isResolvedState: boolean = incidentState?.isResolvedState || false;
211
+
206
212
  if (isResolvedState) {
207
213
  const incident: Incident | null = await IncidentService.findOneBy({
208
214
  query: {
@@ -228,6 +234,24 @@ export class Service extends DatabaseService<IncidentStateTimeline> {
228
234
  }
229
235
  }
230
236
 
237
+ if (onCreate.carryForward.publicNote) {
238
+ const publicNote: string = onCreate.carryForward.publicNote;
239
+
240
+ const incidentPublicNote: IncidentPublicNote = new IncidentPublicNote();
241
+ incidentPublicNote.incidentId = createdItem.incidentId;
242
+ incidentPublicNote.note = publicNote;
243
+ incidentPublicNote.postedAt = createdItem.startsAt!;
244
+ incidentPublicNote.createdAt = createdItem.startsAt!;
245
+ incidentPublicNote.projectId = createdItem.projectId!;
246
+ incidentPublicNote.shouldStatusPageSubscribersBeNotifiedOnNoteCreated =
247
+ Boolean(createdItem.shouldStatusPageSubscribersBeNotified);
248
+
249
+ await IncidentPublicNoteService.create({
250
+ data: incidentPublicNote,
251
+ props: onCreate.createBy.props,
252
+ });
253
+ }
254
+
231
255
  IncidentService.refreshIncidentMetrics({
232
256
  incidentId: createdItem.incidentId,
233
257
  }).catch((error: Error) => {
@@ -147,9 +147,9 @@ import AlertOwnerUserService from "./AlertOwnerUserService";
147
147
  import AlertSeverityService from "./AlertSeverityService";
148
148
  import AlertNoteTemplateService from "./AlertNoteTemplateService";
149
149
  import TableViewService from "./TableViewService";
150
- import ScheduledMaintenanceLogService from "./ScheduledMaintenanceLogService";
151
- import AlertLogService from "./AlertLogService";
152
- import IncidentLogService from "./IncidentLogService";
150
+ import ScheduledMaintenanceFeedService from "./ScheduledMaintenanceFeedService";
151
+ import AlertFeedService from "./AlertFeedService";
152
+ import IncidentFeedService from "./IncidentFeedService";
153
153
 
154
154
  const services: Array<BaseService> = [
155
155
  AcmeCertificateService,
@@ -189,7 +189,7 @@ const services: Array<BaseService> = [
189
189
  IncidentSeverityService,
190
190
  IncidentStateService,
191
191
  IncidentStateTimelineService,
192
- IncidentLogService,
192
+ IncidentFeedService,
193
193
 
194
194
  LabelService,
195
195
 
@@ -226,7 +226,7 @@ const services: Array<BaseService> = [
226
226
  ScheduledMaintenanceService,
227
227
  ScheduledMaintenanceStateService,
228
228
  ScheduledMaintenanceStateTimelineService,
229
- ScheduledMaintenanceLogService,
229
+ ScheduledMaintenanceFeedService,
230
230
 
231
231
  ShortLinkService,
232
232
  SmsLogService,
@@ -311,7 +311,7 @@ const services: Array<BaseService> = [
311
311
  AlertOwnerUserService,
312
312
  AlertSeverityService,
313
313
  AlertNoteTemplateService,
314
- AlertLogService,
314
+ AlertFeedService,
315
315
 
316
316
  TableViewService,
317
317
  ];
@@ -1,5 +1,5 @@
1
1
  import CreateBy from "../Types/Database/CreateBy";
2
- import { OnCreate } from "../Types/Database/Hooks";
2
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
3
3
  import DatabaseService from "./DatabaseService";
4
4
  import OnCallDutyPolicyEscalationRuleService from "./OnCallDutyPolicyEscalationRuleService";
5
5
  import OnCallDutyPolicyStatus from "../../Types/OnCallDutyPolicy/OnCallDutyPolicyStatus";
@@ -7,6 +7,13 @@ import UserNotificationEventType from "../../Types/UserNotification/UserNotifica
7
7
  import OnCallDutyPolicyEscalationRule from "Common/Models/DatabaseModels/OnCallDutyPolicyEscalationRule";
8
8
  import Model from "Common/Models/DatabaseModels/OnCallDutyPolicyExecutionLog";
9
9
  import { IsBillingEnabled } from "../EnvironmentConfig";
10
+ import IncidentFeedService from "./IncidentFeedService";
11
+ import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
12
+ import { Blue500, Green500, Red500, Yellow500 } from "../../Types/BrandColors";
13
+ import OnCallDutyPolicy from "../../Models/DatabaseModels/OnCallDutyPolicy";
14
+ import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
15
+ import ObjectID from "../../Types/ObjectID";
16
+ import Color from "../../Types/Color";
10
17
 
11
18
  export class Service extends DatabaseService<Model> {
12
19
  public constructor() {
@@ -32,6 +39,31 @@ export class Service extends DatabaseService<Model> {
32
39
  _onCreate: OnCreate<Model>,
33
40
  createdItem: Model,
34
41
  ): Promise<Model> {
42
+ if (createdItem.triggeredByIncidentId) {
43
+ const onCallPolicy: OnCallDutyPolicy | null =
44
+ await OnCallDutyPolicyService.findOneById({
45
+ id: createdItem.onCallDutyPolicyId!,
46
+ select: {
47
+ _id: true,
48
+ projectId: true,
49
+ name: true,
50
+ },
51
+ props: {
52
+ isRoot: true,
53
+ },
54
+ });
55
+
56
+ if (onCallPolicy && onCallPolicy.id) {
57
+ await IncidentFeedService.createIncidentFeed({
58
+ incidentId: createdItem.triggeredByIncidentId,
59
+ projectId: createdItem.projectId!,
60
+ incidentFeedEventType: IncidentFeedEventType.OnCallPolicy,
61
+ displayColor: Yellow500,
62
+ feedInfoInMarkdown: `**On Call Policy Started Executing:** On Call Policy **${onCallPolicy.name}** started executing. Users on call on this policy will now be notified.`,
63
+ });
64
+ }
65
+ }
66
+
35
67
  // get execution rules in this policy adn execute the first rule.
36
68
  const executionRule: OnCallDutyPolicyEscalationRule | null =
37
69
  await OnCallDutyPolicyEscalationRuleService.findOneBy({
@@ -97,5 +129,88 @@ export class Service extends DatabaseService<Model> {
97
129
 
98
130
  return createdItem;
99
131
  }
132
+
133
+ public getDisplayColorByStatus(status: OnCallDutyPolicyStatus): Color {
134
+ switch (status) {
135
+ case OnCallDutyPolicyStatus.Scheduled:
136
+ return Blue500;
137
+ case OnCallDutyPolicyStatus.Started:
138
+ return Yellow500;
139
+ case OnCallDutyPolicyStatus.Executing:
140
+ return Yellow500;
141
+ case OnCallDutyPolicyStatus.Completed:
142
+ return Green500;
143
+ case OnCallDutyPolicyStatus.Error:
144
+ return Red500;
145
+ default:
146
+ return Blue500;
147
+ }
148
+ }
149
+
150
+ protected override async onUpdateSuccess(
151
+ onUpdate: OnUpdate<Model>,
152
+ _updatedItemIds: Array<ObjectID>,
153
+ ): Promise<OnUpdate<Model>> {
154
+ // if status is updtaed then check if this on-call is related to the incident, if yes, then add to incident feed.
155
+ if (onUpdate.updateBy.data.status && onUpdate.updateBy.query._id) {
156
+ const id: ObjectID = onUpdate.updateBy.query._id! as ObjectID;
157
+
158
+ const onCalldutyPolicyExecutionLog: Model | null = await this.findOneById(
159
+ {
160
+ id: id,
161
+ select: {
162
+ _id: true,
163
+ projectId: true,
164
+ onCallDutyPolicyId: true,
165
+ status: true,
166
+ statusMessage: true,
167
+ triggeredByIncidentId: true,
168
+ },
169
+ props: {
170
+ isRoot: true,
171
+ },
172
+ },
173
+ );
174
+
175
+ if (
176
+ onCalldutyPolicyExecutionLog &&
177
+ onCalldutyPolicyExecutionLog.triggeredByIncidentId
178
+ ) {
179
+ const onCallPolicy: OnCallDutyPolicy | null =
180
+ await OnCallDutyPolicyService.findOneById({
181
+ id: onCalldutyPolicyExecutionLog.onCallDutyPolicyId!,
182
+ select: {
183
+ _id: true,
184
+ projectId: true,
185
+ name: true,
186
+ },
187
+ props: {
188
+ isRoot: true,
189
+ },
190
+ });
191
+
192
+ if (onCallPolicy && onCallPolicy.id) {
193
+ await IncidentFeedService.createIncidentFeed({
194
+ incidentId: onCalldutyPolicyExecutionLog.triggeredByIncidentId,
195
+ projectId: onCalldutyPolicyExecutionLog.projectId!,
196
+ incidentFeedEventType: IncidentFeedEventType.OnCallPolicy,
197
+ displayColor: onCalldutyPolicyExecutionLog.status
198
+ ? this.getDisplayColorByStatus(
199
+ onCalldutyPolicyExecutionLog.status,
200
+ )
201
+ : Blue500,
202
+ moreInformationInMarkdown: `**Status:** ${onCalldutyPolicyExecutionLog.status}
203
+
204
+ **Message:** ${onCalldutyPolicyExecutionLog.statusMessage}`,
205
+ feedInfoInMarkdown: `**On Call Policy Status Updated:**
206
+
207
+ On-call policy **${onCallPolicy.name}** status updated to **${onCalldutyPolicyExecutionLog.status}**`,
208
+ });
209
+ }
210
+ }
211
+ }
212
+
213
+ return onUpdate;
214
+ }
100
215
  }
101
216
  export default new Service();
@@ -1,9 +1,178 @@
1
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
1
2
  import DatabaseService from "./DatabaseService";
2
3
  import Model from "Common/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline";
4
+ import IncidentFeedService from "./IncidentFeedService";
5
+ import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
6
+ import OnCallDutyExecutionLogTimelineStatus from "../../Types/OnCallDutyPolicy/OnCalDutyExecutionLogTimelineStatus";
7
+ import { Blue500, Green500, Red500, Yellow500 } from "../../Types/BrandColors";
8
+ import Color from "../../Types/Color";
9
+ import ObjectID from "../../Types/ObjectID";
10
+ import logger from "../Utils/Logger";
11
+ import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
3
12
 
4
13
  export class Service extends DatabaseService<Model> {
5
14
  public constructor() {
6
15
  super(Model);
7
16
  }
17
+
18
+ public getColorBasedOnStatus(
19
+ status: OnCallDutyExecutionLogTimelineStatus,
20
+ ): Color {
21
+ switch (status) {
22
+ case OnCallDutyExecutionLogTimelineStatus.Started:
23
+ return Blue500;
24
+ case OnCallDutyExecutionLogTimelineStatus.Executing:
25
+ return Yellow500;
26
+ case OnCallDutyExecutionLogTimelineStatus.Error:
27
+ return Red500;
28
+ case OnCallDutyExecutionLogTimelineStatus.NotificationSent:
29
+ return Green500;
30
+ case OnCallDutyExecutionLogTimelineStatus.Skipped:
31
+ return Red500;
32
+ case OnCallDutyExecutionLogTimelineStatus.SuccessfullyAcknowledged:
33
+ return Green500;
34
+ default:
35
+ return Blue500;
36
+ }
37
+ }
38
+
39
+ public async addToIncidentFeed(data: {
40
+ onCallDutyPolicyExecutionLogTimelineId: ObjectID;
41
+ }): Promise<void> {
42
+ logger.debug(
43
+ "OnCallDutyPolicyExecutionLogTimelineService.addToIncidentFeed",
44
+ );
45
+
46
+ const onCallDutyPolicyExecutionLogTimeline: Model | null =
47
+ await this.findOneById({
48
+ id: data.onCallDutyPolicyExecutionLogTimelineId,
49
+ select: {
50
+ _id: true,
51
+ onCallDutyPolicyId: true,
52
+ triggeredByIncidentId: true,
53
+ projectId: true,
54
+ status: true,
55
+ statusMessage: true,
56
+ alertSentToUserId: true,
57
+ onCallDutyPolicy: {
58
+ name: true,
59
+ _id: true,
60
+ },
61
+ alertSentToUser: {
62
+ name: true,
63
+ email: true,
64
+ },
65
+ onCallDutyPolicyEscalationRule: {
66
+ name: true,
67
+ _id: true,
68
+ },
69
+ onCallDutySchedule: {
70
+ name: true,
71
+ _id: true,
72
+ },
73
+ isAcknowledged: true,
74
+ acknowledgedAt: true,
75
+ userBelongsToTeam: {
76
+ name: true,
77
+ _id: true,
78
+ },
79
+ },
80
+ props: {
81
+ isRoot: true,
82
+ },
83
+ });
84
+
85
+ logger.debug("OnCallDutyPolicyExecutionLogTimeline: ");
86
+ logger.debug(onCallDutyPolicyExecutionLogTimeline);
87
+
88
+ if (!onCallDutyPolicyExecutionLogTimeline) {
89
+ return;
90
+ }
91
+
92
+ if (!onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentId) {
93
+ return;
94
+ }
95
+
96
+ if (
97
+ onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy &&
98
+ onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.id
99
+ ) {
100
+ const status: OnCallDutyExecutionLogTimelineStatus =
101
+ onCallDutyPolicyExecutionLogTimeline.status!;
102
+
103
+ logger.debug("Status: " + status);
104
+
105
+ if (
106
+ status &&
107
+ (status === OnCallDutyExecutionLogTimelineStatus.Skipped ||
108
+ status === OnCallDutyExecutionLogTimelineStatus.Error ||
109
+ status ===
110
+ OnCallDutyExecutionLogTimelineStatus.SuccessfullyAcknowledged ||
111
+ status === OnCallDutyExecutionLogTimelineStatus.NotificationSent)
112
+ ) {
113
+ const displayColor: Color = status
114
+ ? this.getColorBasedOnStatus(status)
115
+ : Blue500;
116
+
117
+ const feedInfoInMarkdown: string = `**On-call alert ${status} to ${onCallDutyPolicyExecutionLogTimeline.alertSentToUser?.name?.toString().trim()}**
118
+
119
+ The on-call policy **${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicy.name}** has been triggered. The escalation rule **${onCallDutyPolicyExecutionLogTimeline.onCallDutyPolicyEscalationRule?.name}** ${onCallDutyPolicyExecutionLogTimeline.onCallDutySchedule?.name ? String(" and schedule **" + onCallDutyPolicyExecutionLogTimeline.onCallDutySchedule?.name + "**") : ""} were applied. The user **${onCallDutyPolicyExecutionLogTimeline.alertSentToUser?.name}** (${onCallDutyPolicyExecutionLogTimeline.alertSentToUser?.email}) was alerted. The status of this alert is **${status}** with the message: \`${onCallDutyPolicyExecutionLogTimeline.statusMessage}\`. ${onCallDutyPolicyExecutionLogTimeline.userBelongsToTeam?.name ? "The alert was sent because the user belogs to the team **" + onCallDutyPolicyExecutionLogTimeline.userBelongsToTeam?.name + "**" : ""} ${onCallDutyPolicyExecutionLogTimeline.isAcknowledged ? "The alert was acknowledged at **" + onCallDutyPolicyExecutionLogTimeline.acknowledgedAt + "**" : ""}`;
120
+
121
+ logger.debug("Feed Info in Markdown: " + feedInfoInMarkdown);
122
+
123
+ await IncidentFeedService.createIncidentFeed({
124
+ incidentId:
125
+ onCallDutyPolicyExecutionLogTimeline.triggeredByIncidentId,
126
+ projectId: onCallDutyPolicyExecutionLogTimeline.projectId!,
127
+ incidentFeedEventType: IncidentFeedEventType.OnCallPolicy,
128
+ displayColor: displayColor,
129
+ feedInfoInMarkdown: feedInfoInMarkdown,
130
+ });
131
+
132
+ logger.debug("Incident Feed created");
133
+ }
134
+ }
135
+ }
136
+
137
+ protected override async onCreateSuccess(
138
+ _onCreate: OnCreate<Model>,
139
+ createdItem: Model,
140
+ ): Promise<Model> {
141
+ logger.debug("OnCallDutyPolicyExecutionLogTimelineService.onCreateSuccess");
142
+ logger.debug(createdItem);
143
+
144
+ await this.addToIncidentFeed({
145
+ onCallDutyPolicyExecutionLogTimelineId: createdItem.id!,
146
+ });
147
+
148
+ return createdItem;
149
+ }
150
+
151
+ protected override async onUpdateSuccess(
152
+ onUpdate: OnUpdate<Model>,
153
+ _updatedItemIds: Array<ObjectID>,
154
+ ): Promise<OnUpdate<Model>> {
155
+ if (onUpdate.updateBy.query) {
156
+ const updatedItems: Array<Model> = await this.findBy({
157
+ query: onUpdate.updateBy.query,
158
+ props: {
159
+ isRoot: true,
160
+ },
161
+ select: {
162
+ _id: true,
163
+ },
164
+ limit: LIMIT_PER_PROJECT,
165
+ skip: 0,
166
+ });
167
+
168
+ for (const updatedItem of updatedItems) {
169
+ await this.addToIncidentFeed({
170
+ onCallDutyPolicyExecutionLogTimelineId: updatedItem.id as ObjectID,
171
+ });
172
+ }
173
+ }
174
+
175
+ return onUpdate;
176
+ }
8
177
  }
9
178
  export default new Service();
@@ -0,0 +1,83 @@
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 DatabaseService from "./DatabaseService";
8
+ import Model, {
9
+ ScheduledMaintenanceFeedEventType,
10
+ } from "Common/Models/DatabaseModels/ScheduledMaintenanceFeed";
11
+
12
+ export class Service extends DatabaseService<Model> {
13
+ public constructor() {
14
+ super(Model);
15
+
16
+ if (IsBillingEnabled) {
17
+ this.hardDeleteItemsOlderThanInDays("createdAt", 120);
18
+ }
19
+ }
20
+
21
+ public async createScheduledMaintenanceFeed(data: {
22
+ scheduledMaintenanceId: ObjectID;
23
+ feedInfoInMarkdown: string;
24
+ scheduledMaintenanceFeedEventType: ScheduledMaintenanceFeedEventType;
25
+ projectId: ObjectID;
26
+ moreInformationInMarkdown?: string | undefined;
27
+ displayColor?: Color | undefined;
28
+ userId?: ObjectID | undefined;
29
+ postedAt?: Date | undefined;
30
+ }): Promise<Model> {
31
+ if (!data.scheduledMaintenanceId) {
32
+ throw new BadDataException("Scheduled Maintenance ID is required");
33
+ }
34
+
35
+ if (!data.feedInfoInMarkdown) {
36
+ throw new BadDataException("Log in markdown is required");
37
+ }
38
+
39
+ if (!data.scheduledMaintenanceFeedEventType) {
40
+ throw new BadDataException("Scheduled Maintenance log event is required");
41
+ }
42
+
43
+ if (!data.projectId) {
44
+ throw new BadDataException("Project ID is required");
45
+ }
46
+
47
+ if (!data.displayColor) {
48
+ data.displayColor = Blue500;
49
+ }
50
+
51
+ const scheduledMaintenanceFeed: Model = new Model();
52
+
53
+ scheduledMaintenanceFeed.displayColor = data.displayColor;
54
+ scheduledMaintenanceFeed.scheduledMaintenanceId =
55
+ data.scheduledMaintenanceId;
56
+ scheduledMaintenanceFeed.feedInfoInMarkdown = data.feedInfoInMarkdown;
57
+ scheduledMaintenanceFeed.scheduledMaintenanceFeedEventType =
58
+ data.scheduledMaintenanceFeedEventType;
59
+ scheduledMaintenanceFeed.projectId = data.projectId;
60
+
61
+ if (data.userId) {
62
+ scheduledMaintenanceFeed.userId = data.userId;
63
+ }
64
+
65
+ if (data.moreInformationInMarkdown) {
66
+ scheduledMaintenanceFeed.moreInformationInMarkdown =
67
+ data.moreInformationInMarkdown;
68
+ }
69
+
70
+ if (!data.postedAt) {
71
+ scheduledMaintenanceFeed.postedAt = OneUptimeDate.getCurrentDate();
72
+ }
73
+
74
+ return await this.create({
75
+ data: scheduledMaintenanceFeed,
76
+ props: {
77
+ isRoot: true,
78
+ },
79
+ });
80
+ }
81
+ }
82
+
83
+ export default new Service();
@@ -145,7 +145,7 @@ export class Service extends DatabaseService<Model> {
145
145
  data: {
146
146
  status: UserNotificationExecutionStatus.Error, // now the worker will pick this up and complete this or mark this as failed.
147
147
  statusMessage:
148
- "No notification rules found. Please add rules in User Settings > On-Call Rules.",
148
+ "No notification rules found for this user. User should add the rules in User Settings > On-Call Rules.",
149
149
  },
150
150
  props: {
151
151
  isRoot: true,
@@ -158,7 +158,7 @@ export class Service extends DatabaseService<Model> {
158
158
  data: {
159
159
  status: OnCallDutyExecutionLogTimelineStatus.Error,
160
160
  statusMessage:
161
- "No notification rules found. Please add rules in User Settings > On-Call Rules.",
161
+ "No notification rules found for this user. User should add the rules in User Settings > On-Call Rules.",
162
162
  },
163
163
  props: {
164
164
  isRoot: true,
@@ -14,7 +14,7 @@ describe("enum ColumnLength", () => {
14
14
  });
15
15
 
16
16
  test("ColumnLength.Color", () => {
17
- expect(ColumnLength.Color).toEqual(7);
17
+ expect(ColumnLength.Color).toEqual(10);
18
18
  });
19
19
 
20
20
  test("ColumnLength.Name", () => {
@@ -5,7 +5,7 @@ enum ColumnLength {
5
5
  Slug = 100,
6
6
  Email = 100,
7
7
  Domain = 100,
8
- Color = 7,
8
+ Color = 10,
9
9
  Name = 50,
10
10
  Description = 500,
11
11
  LongText = 500,
@@ -1,5 +1,5 @@
1
1
  const LIMIT_MAX: number = 10000;
2
- export const LIMIT_PER_PROJECT: number = 1000;
2
+ export const LIMIT_PER_PROJECT: number = 10000;
3
3
  export const LIMIT_INFINITY: number = 999999999;
4
4
  export const DEFAULT_LIMIT: number = 10;
5
5
  export default LIMIT_MAX;
@@ -18,6 +18,7 @@ enum IconProp {
18
18
  Bold = "Bold",
19
19
  Italic = "Italic",
20
20
  Underline = "Underline",
21
+ WrenchScrewdriver = "WrenchScrewdriver",
21
22
  Cube = "Cube",
22
23
  Expand = "Expand",
23
24
  Collapse = "Collapse",