@oneuptime/common 9.4.7 → 9.4.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 (342) hide show
  1. package/Models/DatabaseModels/Alert.ts +76 -0
  2. package/Models/DatabaseModels/AlertEpisode.ts +1201 -0
  3. package/Models/DatabaseModels/AlertEpisodeFeed.ts +529 -0
  4. package/Models/DatabaseModels/AlertEpisodeInternalNote.ts +455 -0
  5. package/Models/DatabaseModels/AlertEpisodeMember.ts +586 -0
  6. package/Models/DatabaseModels/AlertEpisodeOwnerTeam.ts +421 -0
  7. package/Models/DatabaseModels/AlertEpisodeOwnerUser.ts +419 -0
  8. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +523 -0
  9. package/Models/DatabaseModels/AlertFeed.ts +1 -0
  10. package/Models/DatabaseModels/AlertGroupingRule.ts +1432 -0
  11. package/Models/DatabaseModels/Index.ts +18 -0
  12. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +70 -0
  13. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.ts +59 -0
  14. package/Models/DatabaseModels/StatusPageDomain.ts +2 -0
  15. package/Models/DatabaseModels/UserOnCallLog.ts +48 -0
  16. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +49 -0
  17. package/Models/DatabaseModels/WorkspaceNotificationLog.ts +57 -0
  18. package/Server/API/SlackAPI.ts +21 -0
  19. package/Server/API/UserOnCallLogTimelineAPI.ts +65 -25
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.ts +751 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.ts +41 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.ts +29 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.ts +177 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.ts +71 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.ts +35 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.ts +29 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.ts +29 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.ts +35 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.ts +47 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1769469813786-MigrationName.ts +71 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1769517677937-RenameNotificationRuleTypes.ts +67 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +24 -0
  33. package/Server/Services/AlertEpisodeFeedService.ts +94 -0
  34. package/Server/Services/AlertEpisodeInternalNoteService.ts +71 -0
  35. package/Server/Services/AlertEpisodeMemberService.ts +267 -0
  36. package/Server/Services/AlertEpisodeOwnerTeamService.ts +10 -0
  37. package/Server/Services/AlertEpisodeOwnerUserService.ts +10 -0
  38. package/Server/Services/AlertEpisodeService.ts +1096 -0
  39. package/Server/Services/AlertEpisodeStateTimelineService.ts +557 -0
  40. package/Server/Services/AlertGroupingEngineService.ts +1120 -0
  41. package/Server/Services/AlertGroupingRuleService.ts +14 -0
  42. package/Server/Services/AlertService.ts +12 -0
  43. package/Server/Services/CallService.ts +2 -0
  44. package/Server/Services/Index.ts +21 -0
  45. package/Server/Services/MailService.ts +5 -0
  46. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +18 -1
  47. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +64 -2
  48. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +27 -1
  49. package/Server/Services/OnCallDutyPolicyService.ts +16 -1
  50. package/Server/Services/PushNotificationService.ts +1 -0
  51. package/Server/Services/SmsService.ts +2 -0
  52. package/Server/Services/UserNotificationRuleService.ts +641 -10
  53. package/Server/Services/UserNotificationSettingService.ts +23 -0
  54. package/Server/Services/UserOnCallLogService.ts +58 -14
  55. package/Server/Services/WhatsAppService.ts +5 -0
  56. package/Server/Services/WorkspaceNotificationRuleService.ts +26 -0
  57. package/Server/Utils/AnalyticsDatabase/Statement.ts +6 -2
  58. package/Server/Utils/PushNotificationUtil.ts +75 -16
  59. package/Server/Utils/WhatsAppTemplateUtil.ts +13 -0
  60. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.ts +18 -0
  61. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +689 -0
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +16 -0
  63. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +11 -0
  64. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +915 -0
  65. package/Server/Utils/Workspace/Slack/Messages/AlertEpisode.ts +120 -0
  66. package/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.ts +74 -0
  67. package/Tests/Server/Services/AlertEpisodeMemberService.test.ts +200 -0
  68. package/Tests/Server/Services/AlertEpisodeService.test.ts +240 -0
  69. package/Tests/Server/Services/AlertGroupingEngineService.test.ts +542 -0
  70. package/Tests/Server/Services/AlertGroupingRuleService.test.ts +383 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +1 -1
  72. package/Tests/UI/Components/Input.test.tsx +1 -1
  73. package/Tests/UI/Components/TextArea.test.tsx +2 -2
  74. package/Types/BaseDatabase/SortOrder.ts +9 -0
  75. package/Types/Email/EmailTemplateType.ts +6 -0
  76. package/Types/NotificationRule/NotificationRuleType.ts +3 -1
  77. package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
  78. package/Types/Permission.ts +309 -0
  79. package/Types/UserNotification/UserNotificationEventType.ts +1 -0
  80. package/Types/WhatsApp/WhatsAppTemplates.ts +24 -0
  81. package/Types/Workspace/NotificationRules/EventType.ts +1 -0
  82. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +32 -3
  83. package/UI/Components/Accordion/Accordion.tsx +20 -2
  84. package/UI/Components/Alerts/Alert.tsx +1 -0
  85. package/UI/Components/Button/Button.tsx +29 -0
  86. package/UI/Components/CardSelect/CardSelect.tsx +5 -1
  87. package/UI/Components/Checkbox/Checkbox.tsx +7 -3
  88. package/UI/Components/ColorCircle/ColorCircle.tsx +2 -0
  89. package/UI/Components/ColorViewer/ColorViewer.tsx +19 -3
  90. package/UI/Components/CopyableButton/CopyableButton.tsx +22 -5
  91. package/UI/Components/Detail/Detail.tsx +1 -1
  92. package/UI/Components/Dropdown/Dropdown.tsx +14 -1
  93. package/UI/Components/Forms/Fields/FormField.tsx +28 -0
  94. package/UI/Components/FullPageModal/FullPageModal.tsx +35 -4
  95. package/UI/Components/Input/Input.tsx +14 -2
  96. package/UI/Components/Link/Link.tsx +1 -0
  97. package/UI/Components/Loader/Loader.tsx +8 -2
  98. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +76 -1
  99. package/UI/Components/Modal/Modal.tsx +47 -3
  100. package/UI/Components/ModelTable/BaseModelTable.tsx +42 -1
  101. package/UI/Components/MoreMenu/MoreMenu.tsx +84 -2
  102. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +30 -8
  103. package/UI/Components/Pagination/Pagination.tsx +113 -8
  104. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -2
  105. package/UI/Components/Radio/Radio.tsx +21 -3
  106. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +54 -27
  107. package/UI/Components/StatusBubble/StatusBubble.tsx +7 -2
  108. package/UI/Components/Table/TableHeader.tsx +20 -3
  109. package/UI/Components/Tabs/Tab.tsx +16 -1
  110. package/UI/Components/Tabs/Tabs.tsx +12 -1
  111. package/UI/Components/TextArea/TextArea.tsx +12 -2
  112. package/UI/Components/Toggle/Toggle.tsx +14 -3
  113. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  114. package/UI/Components/TopAlert/TopAlert.tsx +2 -0
  115. package/build/dist/Models/DatabaseModels/Alert.js +77 -0
  116. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  117. package/build/dist/Models/DatabaseModels/AlertEpisode.js +1225 -0
  118. package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -0
  119. package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js +553 -0
  120. package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js.map +1 -0
  121. package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js +467 -0
  122. package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js.map +1 -0
  123. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +607 -0
  124. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -0
  125. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js +437 -0
  126. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js.map +1 -0
  127. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js +436 -0
  128. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js.map +1 -0
  129. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +546 -0
  130. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -0
  131. package/build/dist/Models/DatabaseModels/AlertFeed.js +1 -0
  132. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  133. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +1437 -0
  134. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -0
  135. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  136. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  137. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +69 -0
  138. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  139. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js +58 -0
  140. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js.map +1 -1
  141. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +2 -0
  142. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  143. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +47 -0
  144. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  145. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +48 -0
  146. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  147. package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js +58 -0
  148. package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js.map +1 -1
  149. package/build/dist/Server/API/SlackAPI.js +18 -0
  150. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  151. package/build/dist/Server/API/UserOnCallLogTimelineAPI.js +55 -15
  152. package/build/dist/Server/API/UserOnCallLogTimelineAPI.js.map +1 -1
  153. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.js +266 -0
  154. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.js.map +1 -0
  155. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.js +20 -0
  156. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.js.map +1 -0
  157. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.js +16 -0
  158. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.js.map +1 -0
  159. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.js +68 -0
  160. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.js.map +1 -0
  161. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.js +30 -0
  162. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.js.map +1 -0
  163. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.js +18 -0
  164. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.js.map +1 -0
  165. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.js +16 -0
  166. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.js.map +1 -0
  167. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.js +16 -0
  168. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.js.map +1 -0
  169. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.js +18 -0
  170. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.js.map +1 -0
  171. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.js +22 -0
  172. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.js.map +1 -0
  173. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769469813786-MigrationName.js +30 -0
  174. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769469813786-MigrationName.js.map +1 -0
  175. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769517677937-RenameNotificationRuleTypes.js +67 -0
  176. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769517677937-RenameNotificationRuleTypes.js.map +1 -0
  177. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +24 -0
  178. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  179. package/build/dist/Server/Services/AlertEpisodeFeedService.js +83 -0
  180. package/build/dist/Server/Services/AlertEpisodeFeedService.js.map +1 -0
  181. package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js +70 -0
  182. package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js.map +1 -0
  183. package/build/dist/Server/Services/AlertEpisodeMemberService.js +256 -0
  184. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -0
  185. package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js +9 -0
  186. package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js.map +1 -0
  187. package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js +9 -0
  188. package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js.map +1 -0
  189. package/build/dist/Server/Services/AlertEpisodeService.js +973 -0
  190. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -0
  191. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +494 -0
  192. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -0
  193. package/build/dist/Server/Services/AlertGroupingEngineService.js +893 -0
  194. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -0
  195. package/build/dist/Server/Services/AlertGroupingRuleService.js +13 -0
  196. package/build/dist/Server/Services/AlertGroupingRuleService.js.map +1 -0
  197. package/build/dist/Server/Services/AlertService.js +11 -0
  198. package/build/dist/Server/Services/AlertService.js.map +1 -1
  199. package/build/dist/Server/Services/CallService.js +11 -10
  200. package/build/dist/Server/Services/CallService.js.map +1 -1
  201. package/build/dist/Server/Services/Index.js +18 -0
  202. package/build/dist/Server/Services/Index.js.map +1 -1
  203. package/build/dist/Server/Services/MailService.js +3 -0
  204. package/build/dist/Server/Services/MailService.js.map +1 -1
  205. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +10 -1
  206. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  207. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +49 -2
  208. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  209. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +21 -1
  210. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  211. package/build/dist/Server/Services/OnCallDutyPolicyService.js +9 -1
  212. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  213. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  214. package/build/dist/Server/Services/SmsService.js +11 -10
  215. package/build/dist/Server/Services/SmsService.js.map +1 -1
  216. package/build/dist/Server/Services/UserNotificationRuleService.js +521 -43
  217. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  218. package/build/dist/Server/Services/UserNotificationSettingService.js +9 -0
  219. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  220. package/build/dist/Server/Services/UserOnCallLogService.js +48 -12
  221. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  222. package/build/dist/Server/Services/WhatsAppService.js +3 -0
  223. package/build/dist/Server/Services/WhatsAppService.js.map +1 -1
  224. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +25 -0
  225. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  226. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +4 -2
  227. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  228. package/build/dist/Server/Utils/PushNotificationUtil.js +51 -16
  229. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  230. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +8 -0
  231. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  232. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js +17 -0
  233. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js.map +1 -1
  234. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +545 -0
  235. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -0
  236. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +13 -0
  237. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  238. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +10 -0
  239. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  240. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +651 -0
  241. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -0
  242. package/build/dist/Server/Utils/Workspace/Slack/Messages/AlertEpisode.js +100 -0
  243. package/build/dist/Server/Utils/Workspace/Slack/Messages/AlertEpisode.js.map +1 -0
  244. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js +70 -0
  245. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js.map +1 -0
  246. package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js +165 -0
  247. package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js.map +1 -0
  248. package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js +193 -0
  249. package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js.map +1 -0
  250. package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js +412 -0
  251. package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js.map +1 -0
  252. package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js +308 -0
  253. package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js.map +1 -0
  254. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +1 -1
  255. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +1 -1
  256. package/build/dist/Tests/UI/Components/Input.test.js +1 -1
  257. package/build/dist/Tests/UI/Components/Input.test.js.map +1 -1
  258. package/build/dist/Tests/UI/Components/TextArea.test.js +2 -2
  259. package/build/dist/Tests/UI/Components/TextArea.test.js.map +1 -1
  260. package/build/dist/Types/BaseDatabase/SortOrder.js +5 -0
  261. package/build/dist/Types/BaseDatabase/SortOrder.js.map +1 -1
  262. package/build/dist/Types/Email/EmailTemplateType.js +5 -0
  263. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  264. package/build/dist/Types/NotificationRule/NotificationRuleType.js +3 -1
  265. package/build/dist/Types/NotificationRule/NotificationRuleType.js.map +1 -1
  266. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +5 -0
  267. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  268. package/build/dist/Types/Permission.js +264 -0
  269. package/build/dist/Types/Permission.js.map +1 -1
  270. package/build/dist/Types/UserNotification/UserNotificationEventType.js +1 -0
  271. package/build/dist/Types/UserNotification/UserNotificationEventType.js.map +1 -1
  272. package/build/dist/Types/WhatsApp/WhatsAppTemplates.js +15 -0
  273. package/build/dist/Types/WhatsApp/WhatsAppTemplates.js.map +1 -1
  274. package/build/dist/Types/Workspace/NotificationRules/EventType.js +1 -0
  275. package/build/dist/Types/Workspace/NotificationRules/EventType.js.map +1 -1
  276. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +28 -3
  277. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  278. package/build/dist/UI/Components/Accordion/Accordion.js +10 -3
  279. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  280. package/build/dist/UI/Components/Alerts/Alert.js +1 -1
  281. package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
  282. package/build/dist/UI/Components/Button/Button.js +8 -2
  283. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  284. package/build/dist/UI/Components/CardSelect/CardSelect.js +1 -1
  285. package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
  286. package/build/dist/UI/Components/Checkbox/Checkbox.js +2 -2
  287. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  288. package/build/dist/UI/Components/ColorCircle/ColorCircle.js +1 -1
  289. package/build/dist/UI/Components/ColorCircle/ColorCircle.js.map +1 -1
  290. package/build/dist/UI/Components/ColorViewer/ColorViewer.js +12 -3
  291. package/build/dist/UI/Components/ColorViewer/ColorViewer.js.map +1 -1
  292. package/build/dist/UI/Components/CopyableButton/CopyableButton.js +12 -5
  293. package/build/dist/UI/Components/CopyableButton/CopyableButton.js.map +1 -1
  294. package/build/dist/UI/Components/Detail/Detail.js +1 -1
  295. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  296. package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -3
  297. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  298. package/build/dist/UI/Components/Forms/Fields/FormField.js +19 -1
  299. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  300. package/build/dist/UI/Components/FullPageModal/FullPageModal.js +24 -5
  301. package/build/dist/UI/Components/FullPageModal/FullPageModal.js.map +1 -1
  302. package/build/dist/UI/Components/Input/Input.js +3 -3
  303. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  304. package/build/dist/UI/Components/Link/Link.js +1 -1
  305. package/build/dist/UI/Components/Link/Link.js.map +1 -1
  306. package/build/dist/UI/Components/Loader/Loader.js +6 -4
  307. package/build/dist/UI/Components/Loader/Loader.js.map +1 -1
  308. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +56 -3
  309. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  310. package/build/dist/UI/Components/Modal/Modal.js +28 -3
  311. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  312. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +23 -1
  313. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  314. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +67 -6
  315. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  316. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +14 -3
  317. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  318. package/build/dist/UI/Components/Pagination/Pagination.js +69 -13
  319. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  320. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +2 -2
  321. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  322. package/build/dist/UI/Components/Radio/Radio.js +8 -5
  323. package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
  324. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -4
  325. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  326. package/build/dist/UI/Components/StatusBubble/StatusBubble.js +2 -2
  327. package/build/dist/UI/Components/StatusBubble/StatusBubble.js.map +1 -1
  328. package/build/dist/UI/Components/Table/TableHeader.js +12 -4
  329. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  330. package/build/dist/UI/Components/Tabs/Tab.js +8 -1
  331. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  332. package/build/dist/UI/Components/Tabs/Tabs.js +4 -3
  333. package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
  334. package/build/dist/UI/Components/TextArea/TextArea.js +3 -3
  335. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  336. package/build/dist/UI/Components/Toggle/Toggle.js +7 -4
  337. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  338. package/build/dist/UI/Components/Tooltip/Tooltip.js +4 -1
  339. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  340. package/build/dist/UI/Components/TopAlert/TopAlert.js +1 -1
  341. package/build/dist/UI/Components/TopAlert/TopAlert.js.map +1 -1
  342. package/package.json +2 -1
@@ -0,0 +1,973 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import DatabaseService from "./DatabaseService";
11
+ import AlertStateService from "./AlertStateService";
12
+ import BadDataException from "../../Types/Exception/BadDataException";
13
+ import ObjectID from "../../Types/ObjectID";
14
+ import Model from "../../Models/DatabaseModels/AlertEpisode";
15
+ import SortOrder from "../../Types/BaseDatabase/SortOrder";
16
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
17
+ import logger from "../Utils/Logger";
18
+ import AlertEpisodeStateTimeline from "../../Models/DatabaseModels/AlertEpisodeStateTimeline";
19
+ import AlertEpisodeStateTimelineService from "./AlertEpisodeStateTimelineService";
20
+ import { IsBillingEnabled } from "../EnvironmentConfig";
21
+ import OneUptimeDate from "../../Types/Date";
22
+ import AlertEpisodeFeedService from "./AlertEpisodeFeedService";
23
+ import { AlertEpisodeFeedEventType } from "../../Models/DatabaseModels/AlertEpisodeFeed";
24
+ import { Red500, Green500, Yellow500, Purple500, } from "../../Types/BrandColors";
25
+ import URL from "../../Types/API/URL";
26
+ import DatabaseConfig from "../DatabaseConfig";
27
+ import AlertSeverityService from "./AlertSeverityService";
28
+ import AlertEpisodeMemberService from "./AlertEpisodeMemberService";
29
+ import AlertEpisodeOwnerUserService from "./AlertEpisodeOwnerUserService";
30
+ import AlertEpisodeOwnerTeamService from "./AlertEpisodeOwnerTeamService";
31
+ import TeamMemberService from "./TeamMemberService";
32
+ import AlertEpisodeOwnerUser from "../../Models/DatabaseModels/AlertEpisodeOwnerUser";
33
+ import AlertEpisodeOwnerTeam from "../../Models/DatabaseModels/AlertEpisodeOwnerTeam";
34
+ import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
35
+ import Typeof from "../../Types/Typeof";
36
+ import AlertService from "./AlertService";
37
+ import Semaphore from "../Infrastructure/Semaphore";
38
+ import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
39
+ import UserNotificationEventType from "../../Types/UserNotification/UserNotificationEventType";
40
+ export class Service extends DatabaseService {
41
+ constructor() {
42
+ super(Model);
43
+ if (IsBillingEnabled) {
44
+ this.hardDeleteItemsOlderThanInDays("createdAt", 3 * 365); // 3 years
45
+ }
46
+ }
47
+ async getExistingEpisodeNumberForProject(data) {
48
+ const lastEpisode = await this.findOneBy({
49
+ query: {
50
+ projectId: data.projectId,
51
+ },
52
+ select: {
53
+ episodeNumber: true,
54
+ },
55
+ sort: {
56
+ episodeNumber: SortOrder.Descending,
57
+ },
58
+ props: {
59
+ isRoot: true,
60
+ },
61
+ });
62
+ if (!lastEpisode) {
63
+ return 0;
64
+ }
65
+ return lastEpisode.episodeNumber ? Number(lastEpisode.episodeNumber) : 0;
66
+ }
67
+ async onBeforeCreate(createBy) {
68
+ if (!createBy.props.tenantId && !createBy.props.isRoot) {
69
+ throw new BadDataException("ProjectId required to create alert episode.");
70
+ }
71
+ const projectId = createBy.props.tenantId || createBy.data.projectId;
72
+ let mutex = null;
73
+ try {
74
+ // Acquire mutex to prevent race conditions when generating episode numbers
75
+ try {
76
+ mutex = await Semaphore.lock({
77
+ key: projectId.toString(),
78
+ namespace: "AlertEpisode.create",
79
+ });
80
+ }
81
+ catch (err) {
82
+ logger.error(err);
83
+ }
84
+ // Get the created state for episodes
85
+ const alertState = await AlertStateService.findOneBy({
86
+ query: {
87
+ projectId: projectId,
88
+ isCreatedState: true,
89
+ },
90
+ select: {
91
+ _id: true,
92
+ },
93
+ props: {
94
+ isRoot: true,
95
+ },
96
+ });
97
+ if (!alertState || !alertState.id) {
98
+ throw new BadDataException("Created alert state not found for this project. Please add created alert state from settings.");
99
+ }
100
+ createBy.data.currentAlertStateId = alertState.id;
101
+ // Auto-generate episode number
102
+ const episodeNumberForThisEpisode = (await this.getExistingEpisodeNumberForProject({
103
+ projectId: projectId,
104
+ })) + 1;
105
+ createBy.data.episodeNumber = episodeNumberForThisEpisode;
106
+ // Set initial lastAlertAddedAt
107
+ if (!createBy.data.lastAlertAddedAt) {
108
+ createBy.data.lastAlertAddedAt = OneUptimeDate.getCurrentDate();
109
+ }
110
+ return { createBy, carryForward: { mutex } };
111
+ }
112
+ catch (error) {
113
+ // Release the mutex if it was acquired and an error occurred
114
+ if (mutex) {
115
+ try {
116
+ await Semaphore.release(mutex);
117
+ }
118
+ catch (err) {
119
+ logger.error(err);
120
+ }
121
+ }
122
+ throw error;
123
+ }
124
+ }
125
+ async onCreateSuccess(onCreate, createdItem) {
126
+ var _a;
127
+ // Release the mutex acquired in onBeforeCreate
128
+ const mutex = ((_a = onCreate.carryForward) === null || _a === void 0 ? void 0 : _a.mutex) || null;
129
+ if (mutex) {
130
+ try {
131
+ await Semaphore.release(mutex);
132
+ }
133
+ catch (err) {
134
+ logger.error(err);
135
+ }
136
+ }
137
+ if (!createdItem.projectId) {
138
+ throw new BadDataException("projectId is required");
139
+ }
140
+ if (!createdItem.id) {
141
+ throw new BadDataException("id is required");
142
+ }
143
+ if (!createdItem.currentAlertStateId) {
144
+ throw new BadDataException("currentAlertStateId is required");
145
+ }
146
+ // Create initial state timeline entry
147
+ Promise.resolve()
148
+ .then(async () => {
149
+ try {
150
+ await this.changeEpisodeState({
151
+ projectId: createdItem.projectId,
152
+ episodeId: createdItem.id,
153
+ alertStateId: createdItem.currentAlertStateId,
154
+ notifyOwners: false,
155
+ rootCause: undefined,
156
+ props: {
157
+ isRoot: true,
158
+ },
159
+ });
160
+ }
161
+ catch (error) {
162
+ logger.error(`Handle episode state change failed in AlertEpisodeService.onCreateSuccess: ${error}`);
163
+ }
164
+ })
165
+ .then(async () => {
166
+ try {
167
+ await this.createEpisodeCreatedFeed(createdItem);
168
+ }
169
+ catch (error) {
170
+ logger.error(`Create episode feed failed in AlertEpisodeService.onCreateSuccess: ${error}`);
171
+ }
172
+ })
173
+ .then(async () => {
174
+ // Execute on-call duty policies
175
+ try {
176
+ await this.executeEpisodeOnCallDutyPoliciesAsync(createdItem);
177
+ }
178
+ catch (error) {
179
+ logger.error(`On-call duty policy execution failed in AlertEpisodeService.onCreateSuccess: ${error}`);
180
+ }
181
+ })
182
+ .catch((error) => {
183
+ logger.error(`Critical error in AlertEpisodeService.onCreateSuccess: ${error}`);
184
+ });
185
+ return createdItem;
186
+ }
187
+ async createEpisodeCreatedFeed(episode) {
188
+ var _a;
189
+ if (!episode.id || !episode.projectId) {
190
+ return;
191
+ }
192
+ let feedInfoInMarkdown = `#### Episode ${(_a = episode.episodeNumber) === null || _a === void 0 ? void 0 : _a.toString()} Created
193
+
194
+ **${episode.title || "No title provided."}**
195
+
196
+ `;
197
+ if (episode.description) {
198
+ feedInfoInMarkdown += `${episode.description}\n\n`;
199
+ }
200
+ if (episode.isManuallyCreated) {
201
+ feedInfoInMarkdown += `This episode was manually created.\n\n`;
202
+ }
203
+ await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
204
+ alertEpisodeId: episode.id,
205
+ projectId: episode.projectId,
206
+ alertEpisodeFeedEventType: AlertEpisodeFeedEventType.EpisodeCreated,
207
+ displayColor: Red500,
208
+ feedInfoInMarkdown: feedInfoInMarkdown,
209
+ userId: episode.createdByUserId || undefined,
210
+ });
211
+ }
212
+ async executeEpisodeOnCallDutyPoliciesAsync(createdItem) {
213
+ var _a;
214
+ if (!createdItem.id || !createdItem.projectId) {
215
+ return;
216
+ }
217
+ try {
218
+ // Fetch the episode with on-call duty policies since they may not be loaded
219
+ const episodeWithPolicies = await this.findOneById({
220
+ id: createdItem.id,
221
+ select: {
222
+ onCallDutyPolicies: {
223
+ _id: true,
224
+ name: true,
225
+ },
226
+ },
227
+ props: {
228
+ isRoot: true,
229
+ },
230
+ });
231
+ if (!((_a = episodeWithPolicies === null || episodeWithPolicies === void 0 ? void 0 : episodeWithPolicies.onCallDutyPolicies) === null || _a === void 0 ? void 0 : _a.length) ||
232
+ episodeWithPolicies.onCallDutyPolicies.length === 0) {
233
+ return;
234
+ }
235
+ // Execute all on-call policies in parallel
236
+ const policyPromises = episodeWithPolicies.onCallDutyPolicies.map((policy) => {
237
+ return OnCallDutyPolicyService.executePolicy(new ObjectID(policy._id), {
238
+ triggeredByAlertEpisodeId: createdItem.id,
239
+ userNotificationEventType: UserNotificationEventType.AlertEpisodeCreated,
240
+ });
241
+ });
242
+ await Promise.allSettled(policyPromises);
243
+ // Update the flag to indicate on-call policy has been executed
244
+ await this.updateOneById({
245
+ id: createdItem.id,
246
+ data: {
247
+ isOnCallPolicyExecuted: true,
248
+ },
249
+ props: {
250
+ isRoot: true,
251
+ },
252
+ });
253
+ // Create feed entry for on-call policy execution
254
+ const policyNames = episodeWithPolicies.onCallDutyPolicies
255
+ .map((policy) => {
256
+ return policy.name || "Unnamed Policy";
257
+ })
258
+ .filter((name) => {
259
+ return Boolean(name);
260
+ });
261
+ let feedInfoInMarkdown = `#### On-Call Policy Executed\n\n`;
262
+ feedInfoInMarkdown += `The following on-call ${policyNames.length === 1 ? "policy has" : "policies have"} been executed for this episode:\n\n`;
263
+ for (const policyName of policyNames) {
264
+ feedInfoInMarkdown += `- ${policyName}\n`;
265
+ }
266
+ await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
267
+ alertEpisodeId: createdItem.id,
268
+ projectId: createdItem.projectId,
269
+ alertEpisodeFeedEventType: AlertEpisodeFeedEventType.OnCallPolicy,
270
+ displayColor: Purple500,
271
+ feedInfoInMarkdown: feedInfoInMarkdown,
272
+ });
273
+ }
274
+ catch (error) {
275
+ logger.error(`Error in executeEpisodeOnCallDutyPoliciesAsync: ${error}`);
276
+ throw error;
277
+ }
278
+ }
279
+ async changeEpisodeState(data) {
280
+ const { projectId, episodeId, alertStateId, notifyOwners, rootCause, props, cascadeToAlerts, } = data;
281
+ // Get last episode state timeline
282
+ const lastEpisodeStateTimeline = await AlertEpisodeStateTimelineService.findOneBy({
283
+ query: {
284
+ alertEpisodeId: episodeId,
285
+ projectId: projectId,
286
+ },
287
+ select: {
288
+ _id: true,
289
+ alertStateId: true,
290
+ },
291
+ sort: {
292
+ createdAt: SortOrder.Descending,
293
+ },
294
+ props: {
295
+ isRoot: true,
296
+ },
297
+ });
298
+ if (lastEpisodeStateTimeline &&
299
+ lastEpisodeStateTimeline.alertStateId &&
300
+ lastEpisodeStateTimeline.alertStateId.toString() ===
301
+ alertStateId.toString()) {
302
+ return;
303
+ }
304
+ const stateTimeline = new AlertEpisodeStateTimeline();
305
+ stateTimeline.alertEpisodeId = episodeId;
306
+ stateTimeline.alertStateId = alertStateId;
307
+ stateTimeline.projectId = projectId;
308
+ stateTimeline.isOwnerNotified = !notifyOwners;
309
+ if (rootCause) {
310
+ stateTimeline.rootCause = rootCause;
311
+ }
312
+ await AlertEpisodeStateTimelineService.create({
313
+ data: stateTimeline,
314
+ props: props || {},
315
+ });
316
+ /*
317
+ * Note: resolvedAt is updated by AlertEpisodeStateTimelineService.onCreateSuccess()
318
+ * to avoid duplicate updates.
319
+ */
320
+ // Cascade state change to all member alerts if requested
321
+ if (cascadeToAlerts) {
322
+ await this.cascadeStateToMemberAlerts({
323
+ projectId,
324
+ episodeId,
325
+ alertStateId,
326
+ props,
327
+ });
328
+ }
329
+ }
330
+ async cascadeStateToMemberAlerts(data) {
331
+ const { projectId, episodeId, alertStateId, props } = data;
332
+ // Get all member alerts for this episode
333
+ const members = await AlertEpisodeMemberService.findBy({
334
+ query: {
335
+ alertEpisodeId: episodeId,
336
+ projectId: projectId,
337
+ },
338
+ select: {
339
+ alertId: true,
340
+ },
341
+ props: {
342
+ isRoot: true,
343
+ },
344
+ limit: LIMIT_PER_PROJECT,
345
+ skip: 0,
346
+ });
347
+ if (members.length === 0) {
348
+ return;
349
+ }
350
+ // Update state for each member alert
351
+ for (const member of members) {
352
+ if (!member.alertId) {
353
+ continue;
354
+ }
355
+ try {
356
+ await AlertService.changeAlertState({
357
+ projectId: projectId,
358
+ alertId: member.alertId,
359
+ alertStateId: alertStateId,
360
+ notifyOwners: false, // Don't send notifications for cascaded state changes
361
+ rootCause: "State changed by episode state cascade.",
362
+ stateChangeLog: undefined,
363
+ props: props,
364
+ });
365
+ }
366
+ catch (error) {
367
+ logger.error(`Failed to cascade state change to alert ${member.alertId.toString()}: ${error}`);
368
+ }
369
+ }
370
+ }
371
+ async acknowledgeEpisode(episodeId, acknowledgedByUserId, cascadeToAlerts = true) {
372
+ const episode = await this.findOneById({
373
+ id: episodeId,
374
+ select: {
375
+ projectId: true,
376
+ },
377
+ props: {
378
+ isRoot: true,
379
+ },
380
+ });
381
+ if (!episode || !episode.projectId) {
382
+ throw new BadDataException("Episode not found.");
383
+ }
384
+ const alertState = await AlertStateService.findOneBy({
385
+ query: {
386
+ projectId: episode.projectId,
387
+ isAcknowledgedState: true,
388
+ },
389
+ select: {
390
+ _id: true,
391
+ },
392
+ props: {
393
+ isRoot: true,
394
+ },
395
+ });
396
+ if (!alertState || !alertState.id) {
397
+ throw new BadDataException("Acknowledged state not found for this project.");
398
+ }
399
+ await this.changeEpisodeState({
400
+ projectId: episode.projectId,
401
+ episodeId: episodeId,
402
+ alertStateId: alertState.id,
403
+ notifyOwners: true,
404
+ rootCause: undefined,
405
+ props: {
406
+ isRoot: true,
407
+ userId: acknowledgedByUserId,
408
+ },
409
+ cascadeToAlerts: cascadeToAlerts,
410
+ });
411
+ // Create feed for episode acknowledged
412
+ let feedMessage = "Episode has been acknowledged.";
413
+ if (cascadeToAlerts) {
414
+ feedMessage += " All member alerts have also been acknowledged.";
415
+ }
416
+ await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
417
+ alertEpisodeId: episodeId,
418
+ projectId: episode.projectId,
419
+ alertEpisodeFeedEventType: AlertEpisodeFeedEventType.EpisodeStateChanged,
420
+ displayColor: Yellow500,
421
+ feedInfoInMarkdown: feedMessage,
422
+ userId: acknowledgedByUserId || undefined,
423
+ });
424
+ }
425
+ async resolveEpisode(episodeId, resolvedByUserId, cascadeToAlerts = true) {
426
+ const episode = await this.findOneById({
427
+ id: episodeId,
428
+ select: {
429
+ projectId: true,
430
+ },
431
+ props: {
432
+ isRoot: true,
433
+ },
434
+ });
435
+ if (!episode || !episode.projectId) {
436
+ throw new BadDataException("Episode not found.");
437
+ }
438
+ const alertState = await AlertStateService.findOneBy({
439
+ query: {
440
+ projectId: episode.projectId,
441
+ isResolvedState: true,
442
+ },
443
+ select: {
444
+ _id: true,
445
+ },
446
+ props: {
447
+ isRoot: true,
448
+ },
449
+ });
450
+ if (!alertState || !alertState.id) {
451
+ throw new BadDataException("Resolved state not found for this project.");
452
+ }
453
+ await this.changeEpisodeState({
454
+ projectId: episode.projectId,
455
+ episodeId: episodeId,
456
+ alertStateId: alertState.id,
457
+ notifyOwners: true,
458
+ rootCause: undefined,
459
+ props: {
460
+ isRoot: true,
461
+ userId: resolvedByUserId,
462
+ },
463
+ cascadeToAlerts: cascadeToAlerts,
464
+ });
465
+ // Create feed for episode resolved
466
+ let feedMessage = "Episode has been resolved.";
467
+ if (cascadeToAlerts) {
468
+ feedMessage += " All member alerts have also been resolved.";
469
+ }
470
+ await AlertEpisodeFeedService.createAlertEpisodeFeedItem({
471
+ alertEpisodeId: episodeId,
472
+ projectId: episode.projectId,
473
+ alertEpisodeFeedEventType: AlertEpisodeFeedEventType.EpisodeStateChanged,
474
+ displayColor: Green500,
475
+ feedInfoInMarkdown: feedMessage,
476
+ userId: resolvedByUserId || undefined,
477
+ });
478
+ }
479
+ async updateEpisodeSeverity(data) {
480
+ var _a;
481
+ const { episodeId, severityId, onlyIfHigher } = data;
482
+ const episode = await this.findOneById({
483
+ id: episodeId,
484
+ select: {
485
+ alertSeverityId: true,
486
+ alertSeverity: {
487
+ order: true,
488
+ },
489
+ },
490
+ props: {
491
+ isRoot: true,
492
+ },
493
+ });
494
+ if (!episode) {
495
+ throw new BadDataException("Episode not found.");
496
+ }
497
+ if (onlyIfHigher && ((_a = episode.alertSeverity) === null || _a === void 0 ? void 0 : _a.order) !== undefined) {
498
+ // Get the new severity to check its order
499
+ const newSeverity = await AlertSeverityService.findOneById({
500
+ id: severityId,
501
+ select: {
502
+ order: true,
503
+ },
504
+ props: {
505
+ isRoot: true,
506
+ },
507
+ });
508
+ if (newSeverity && newSeverity.order !== undefined) {
509
+ // Lower order = higher severity
510
+ if (newSeverity.order >= episode.alertSeverity.order) {
511
+ return; // Don't update if new severity is not higher
512
+ }
513
+ }
514
+ }
515
+ await this.updateOneById({
516
+ id: episodeId,
517
+ data: {
518
+ alertSeverityId: severityId,
519
+ },
520
+ props: {
521
+ isRoot: true,
522
+ },
523
+ });
524
+ }
525
+ async updateAlertCount(episodeId) {
526
+ const count = await AlertEpisodeMemberService.countBy({
527
+ query: {
528
+ alertEpisodeId: episodeId,
529
+ },
530
+ props: {
531
+ isRoot: true,
532
+ },
533
+ });
534
+ const alertCount = count.toNumber();
535
+ // Get the episode to check for templates
536
+ const episode = await this.findOneById({
537
+ id: episodeId,
538
+ select: {
539
+ titleTemplate: true,
540
+ descriptionTemplate: true,
541
+ title: true,
542
+ description: true,
543
+ },
544
+ props: {
545
+ isRoot: true,
546
+ },
547
+ });
548
+ const updateData = {
549
+ alertCount: alertCount,
550
+ };
551
+ // Update title with dynamic variables if template exists
552
+ if (episode === null || episode === void 0 ? void 0 : episode.titleTemplate) {
553
+ updateData.title = this.renderTemplateWithDynamicValues(episode.titleTemplate, alertCount);
554
+ }
555
+ // Update description with dynamic variables if template exists
556
+ if (episode === null || episode === void 0 ? void 0 : episode.descriptionTemplate) {
557
+ updateData.description = this.renderTemplateWithDynamicValues(episode.descriptionTemplate, alertCount);
558
+ }
559
+ await this.updateOneById({
560
+ id: episodeId,
561
+ data: updateData,
562
+ props: {
563
+ isRoot: true,
564
+ },
565
+ });
566
+ }
567
+ renderTemplateWithDynamicValues(template, alertCount) {
568
+ let result = template;
569
+ // Replace dynamic variables
570
+ result = result.replace(/\{\{alertCount\}\}/g, alertCount.toString());
571
+ return result;
572
+ }
573
+ async updateLastAlertAddedAt(episodeId) {
574
+ await this.updateOneById({
575
+ id: episodeId,
576
+ data: {
577
+ lastAlertAddedAt: OneUptimeDate.getCurrentDate(),
578
+ },
579
+ props: {
580
+ isRoot: true,
581
+ },
582
+ });
583
+ }
584
+ async isEpisodeResolved(episodeId) {
585
+ var _a;
586
+ const episode = await this.findOneById({
587
+ id: episodeId,
588
+ select: {
589
+ projectId: true,
590
+ currentAlertState: {
591
+ order: true,
592
+ },
593
+ },
594
+ props: {
595
+ isRoot: true,
596
+ },
597
+ });
598
+ if (!episode || !episode.projectId) {
599
+ throw new BadDataException("Episode not found.");
600
+ }
601
+ const resolvedState = await AlertStateService.getResolvedAlertState({
602
+ projectId: episode.projectId,
603
+ props: {
604
+ isRoot: true,
605
+ },
606
+ });
607
+ const currentOrder = ((_a = episode.currentAlertState) === null || _a === void 0 ? void 0 : _a.order) || 0;
608
+ const resolvedOrder = resolvedState.order || 0;
609
+ return currentOrder >= resolvedOrder;
610
+ }
611
+ async isEpisodeAcknowledged(data) {
612
+ var _a;
613
+ const episode = await this.findOneById({
614
+ id: data.episodeId,
615
+ select: {
616
+ projectId: true,
617
+ currentAlertState: {
618
+ order: true,
619
+ },
620
+ },
621
+ props: {
622
+ isRoot: true,
623
+ },
624
+ });
625
+ if (!episode || !episode.projectId) {
626
+ throw new BadDataException("Episode not found.");
627
+ }
628
+ const acknowledgedState = await AlertStateService.getAcknowledgedAlertState({
629
+ projectId: episode.projectId,
630
+ props: {
631
+ isRoot: true,
632
+ },
633
+ });
634
+ const currentOrder = ((_a = episode.currentAlertState) === null || _a === void 0 ? void 0 : _a.order) || 0;
635
+ const acknowledgedOrder = acknowledgedState.order || 0;
636
+ return currentOrder >= acknowledgedOrder;
637
+ }
638
+ async reopenEpisode(episodeId, reopenedByUserId) {
639
+ const episode = await this.findOneById({
640
+ id: episodeId,
641
+ select: {
642
+ projectId: true,
643
+ },
644
+ props: {
645
+ isRoot: true,
646
+ },
647
+ });
648
+ if (!episode || !episode.projectId) {
649
+ throw new BadDataException("Episode not found.");
650
+ }
651
+ // Get the created state
652
+ const createdState = await AlertStateService.findOneBy({
653
+ query: {
654
+ projectId: episode.projectId,
655
+ isCreatedState: true,
656
+ },
657
+ select: {
658
+ _id: true,
659
+ },
660
+ props: {
661
+ isRoot: true,
662
+ },
663
+ });
664
+ if (!createdState || !createdState.id) {
665
+ throw new BadDataException("Created state not found for this project.");
666
+ }
667
+ await this.changeEpisodeState({
668
+ projectId: episode.projectId,
669
+ episodeId: episodeId,
670
+ alertStateId: createdState.id,
671
+ notifyOwners: true,
672
+ rootCause: "Episode reopened due to new alert added.",
673
+ props: {
674
+ isRoot: true,
675
+ userId: reopenedByUserId,
676
+ },
677
+ });
678
+ // Clear resolved timestamp
679
+ await this.updateOneById({
680
+ id: episodeId,
681
+ data: {
682
+ resolvedAt: undefined,
683
+ },
684
+ props: {
685
+ isRoot: true,
686
+ },
687
+ });
688
+ }
689
+ async getEpisodeLinkInDashboard(projectId, episodeId) {
690
+ const dashboardUrl = await DatabaseConfig.getDashboardUrl();
691
+ return URL.fromString(dashboardUrl.toString()).addRoute(`/${projectId.toString()}/alerts/episodes/${episodeId.toString()}`);
692
+ }
693
+ async getEpisodeNumber(data) {
694
+ const episode = await this.findOneById({
695
+ id: data.episodeId,
696
+ select: {
697
+ episodeNumber: true,
698
+ },
699
+ props: {
700
+ isRoot: true,
701
+ },
702
+ });
703
+ if (!episode) {
704
+ throw new BadDataException("Episode not found.");
705
+ }
706
+ return episode.episodeNumber ? Number(episode.episodeNumber) : null;
707
+ }
708
+ async onUpdateSuccess(onUpdate, updatedItemIds) {
709
+ // Handle state changes
710
+ if (onUpdate.updateBy.data.currentAlertStateId &&
711
+ onUpdate.updateBy.props.tenantId) {
712
+ for (const itemId of updatedItemIds) {
713
+ await this.changeEpisodeState({
714
+ projectId: onUpdate.updateBy.props.tenantId,
715
+ episodeId: itemId,
716
+ alertStateId: onUpdate.updateBy.data.currentAlertStateId,
717
+ notifyOwners: true,
718
+ rootCause: "State was changed when the episode was updated.",
719
+ props: {
720
+ isRoot: true,
721
+ },
722
+ });
723
+ }
724
+ }
725
+ return onUpdate;
726
+ }
727
+ async findOwners(episodeId) {
728
+ // Get direct user owners
729
+ const ownerUsers = await AlertEpisodeOwnerUserService.findBy({
730
+ query: {
731
+ alertEpisodeId: episodeId,
732
+ },
733
+ select: {
734
+ _id: true,
735
+ user: {
736
+ _id: true,
737
+ email: true,
738
+ name: true,
739
+ timezone: true,
740
+ },
741
+ },
742
+ props: {
743
+ isRoot: true,
744
+ },
745
+ limit: LIMIT_PER_PROJECT,
746
+ skip: 0,
747
+ });
748
+ // Get team owners
749
+ const ownerTeams = await AlertEpisodeOwnerTeamService.findBy({
750
+ query: {
751
+ alertEpisodeId: episodeId,
752
+ },
753
+ select: {
754
+ _id: true,
755
+ teamId: true,
756
+ },
757
+ props: {
758
+ isRoot: true,
759
+ },
760
+ limit: LIMIT_PER_PROJECT,
761
+ skip: 0,
762
+ });
763
+ const users = ownerUsers
764
+ .map((ownerUser) => {
765
+ return ownerUser.user;
766
+ })
767
+ .filter((user) => {
768
+ return Boolean(user);
769
+ });
770
+ // Expand teams to individual users
771
+ if (ownerTeams.length > 0) {
772
+ const teamIds = ownerTeams.map((ownerTeam) => {
773
+ return ownerTeam.teamId;
774
+ });
775
+ const teamUsers = await TeamMemberService.getUsersInTeams(teamIds);
776
+ for (const teamUser of teamUsers) {
777
+ // Avoid duplicates
778
+ if (!users.find((user) => {
779
+ var _a, _b;
780
+ return ((_a = user.id) === null || _a === void 0 ? void 0 : _a.toString()) === ((_b = teamUser.id) === null || _b === void 0 ? void 0 : _b.toString());
781
+ })) {
782
+ users.push(teamUser);
783
+ }
784
+ }
785
+ }
786
+ return users;
787
+ }
788
+ async getWorkspaceChannelForEpisode(data) {
789
+ const episode = await this.findOneById({
790
+ id: data.episodeId,
791
+ select: {
792
+ postUpdatesToWorkspaceChannels: true,
793
+ },
794
+ props: {
795
+ isRoot: true,
796
+ },
797
+ });
798
+ if (!episode) {
799
+ throw new BadDataException("Alert Episode not found.");
800
+ }
801
+ return (episode.postUpdatesToWorkspaceChannels || []).filter((channel) => {
802
+ if (!data.workspaceType) {
803
+ return true;
804
+ }
805
+ return channel.workspaceType === data.workspaceType;
806
+ });
807
+ }
808
+ async addOwners(projectId, episodeId, userIds, teamIds, notifyOwners, props) {
809
+ for (let teamId of teamIds) {
810
+ if (typeof teamId === Typeof.String) {
811
+ teamId = new ObjectID(teamId.toString());
812
+ }
813
+ const teamOwner = new AlertEpisodeOwnerTeam();
814
+ teamOwner.alertEpisodeId = episodeId;
815
+ teamOwner.projectId = projectId;
816
+ teamOwner.teamId = teamId;
817
+ teamOwner.isOwnerNotified = !notifyOwners;
818
+ await AlertEpisodeOwnerTeamService.create({
819
+ data: teamOwner,
820
+ props: props,
821
+ });
822
+ }
823
+ for (let userId of userIds) {
824
+ if (typeof userId === Typeof.String) {
825
+ userId = new ObjectID(userId.toString());
826
+ }
827
+ const userOwner = new AlertEpisodeOwnerUser();
828
+ userOwner.alertEpisodeId = episodeId;
829
+ userOwner.projectId = projectId;
830
+ userOwner.userId = userId;
831
+ userOwner.isOwnerNotified = !notifyOwners;
832
+ await AlertEpisodeOwnerUserService.create({
833
+ data: userOwner,
834
+ props: props,
835
+ });
836
+ }
837
+ }
838
+ }
839
+ __decorate([
840
+ CaptureSpan(),
841
+ __metadata("design:type", Function),
842
+ __metadata("design:paramtypes", [Object]),
843
+ __metadata("design:returntype", Promise)
844
+ ], Service.prototype, "getExistingEpisodeNumberForProject", null);
845
+ __decorate([
846
+ CaptureSpan(),
847
+ __metadata("design:type", Function),
848
+ __metadata("design:paramtypes", [Object]),
849
+ __metadata("design:returntype", Promise)
850
+ ], Service.prototype, "onBeforeCreate", null);
851
+ __decorate([
852
+ CaptureSpan(),
853
+ __metadata("design:type", Function),
854
+ __metadata("design:paramtypes", [Object, Model]),
855
+ __metadata("design:returntype", Promise)
856
+ ], Service.prototype, "onCreateSuccess", null);
857
+ __decorate([
858
+ CaptureSpan(),
859
+ __metadata("design:type", Function),
860
+ __metadata("design:paramtypes", [Model]),
861
+ __metadata("design:returntype", Promise)
862
+ ], Service.prototype, "createEpisodeCreatedFeed", null);
863
+ __decorate([
864
+ CaptureSpan(),
865
+ __metadata("design:type", Function),
866
+ __metadata("design:paramtypes", [Model]),
867
+ __metadata("design:returntype", Promise)
868
+ ], Service.prototype, "executeEpisodeOnCallDutyPoliciesAsync", null);
869
+ __decorate([
870
+ CaptureSpan(),
871
+ __metadata("design:type", Function),
872
+ __metadata("design:paramtypes", [Object]),
873
+ __metadata("design:returntype", Promise)
874
+ ], Service.prototype, "changeEpisodeState", null);
875
+ __decorate([
876
+ CaptureSpan(),
877
+ __metadata("design:type", Function),
878
+ __metadata("design:paramtypes", [Object]),
879
+ __metadata("design:returntype", Promise)
880
+ ], Service.prototype, "cascadeStateToMemberAlerts", null);
881
+ __decorate([
882
+ CaptureSpan(),
883
+ __metadata("design:type", Function),
884
+ __metadata("design:paramtypes", [ObjectID,
885
+ ObjectID, Boolean]),
886
+ __metadata("design:returntype", Promise)
887
+ ], Service.prototype, "acknowledgeEpisode", null);
888
+ __decorate([
889
+ CaptureSpan(),
890
+ __metadata("design:type", Function),
891
+ __metadata("design:paramtypes", [ObjectID,
892
+ ObjectID, Boolean]),
893
+ __metadata("design:returntype", Promise)
894
+ ], Service.prototype, "resolveEpisode", null);
895
+ __decorate([
896
+ CaptureSpan(),
897
+ __metadata("design:type", Function),
898
+ __metadata("design:paramtypes", [Object]),
899
+ __metadata("design:returntype", Promise)
900
+ ], Service.prototype, "updateEpisodeSeverity", null);
901
+ __decorate([
902
+ CaptureSpan(),
903
+ __metadata("design:type", Function),
904
+ __metadata("design:paramtypes", [ObjectID]),
905
+ __metadata("design:returntype", Promise)
906
+ ], Service.prototype, "updateAlertCount", null);
907
+ __decorate([
908
+ CaptureSpan(),
909
+ __metadata("design:type", Function),
910
+ __metadata("design:paramtypes", [ObjectID]),
911
+ __metadata("design:returntype", Promise)
912
+ ], Service.prototype, "updateLastAlertAddedAt", null);
913
+ __decorate([
914
+ CaptureSpan(),
915
+ __metadata("design:type", Function),
916
+ __metadata("design:paramtypes", [ObjectID]),
917
+ __metadata("design:returntype", Promise)
918
+ ], Service.prototype, "isEpisodeResolved", null);
919
+ __decorate([
920
+ CaptureSpan(),
921
+ __metadata("design:type", Function),
922
+ __metadata("design:paramtypes", [Object]),
923
+ __metadata("design:returntype", Promise)
924
+ ], Service.prototype, "isEpisodeAcknowledged", null);
925
+ __decorate([
926
+ CaptureSpan(),
927
+ __metadata("design:type", Function),
928
+ __metadata("design:paramtypes", [ObjectID,
929
+ ObjectID]),
930
+ __metadata("design:returntype", Promise)
931
+ ], Service.prototype, "reopenEpisode", null);
932
+ __decorate([
933
+ CaptureSpan(),
934
+ __metadata("design:type", Function),
935
+ __metadata("design:paramtypes", [ObjectID,
936
+ ObjectID]),
937
+ __metadata("design:returntype", Promise)
938
+ ], Service.prototype, "getEpisodeLinkInDashboard", null);
939
+ __decorate([
940
+ CaptureSpan(),
941
+ __metadata("design:type", Function),
942
+ __metadata("design:paramtypes", [Object]),
943
+ __metadata("design:returntype", Promise)
944
+ ], Service.prototype, "getEpisodeNumber", null);
945
+ __decorate([
946
+ CaptureSpan(),
947
+ __metadata("design:type", Function),
948
+ __metadata("design:paramtypes", [Object, Array]),
949
+ __metadata("design:returntype", Promise)
950
+ ], Service.prototype, "onUpdateSuccess", null);
951
+ __decorate([
952
+ CaptureSpan(),
953
+ __metadata("design:type", Function),
954
+ __metadata("design:paramtypes", [ObjectID]),
955
+ __metadata("design:returntype", Promise)
956
+ ], Service.prototype, "findOwners", null);
957
+ __decorate([
958
+ CaptureSpan(),
959
+ __metadata("design:type", Function),
960
+ __metadata("design:paramtypes", [Object]),
961
+ __metadata("design:returntype", Promise)
962
+ ], Service.prototype, "getWorkspaceChannelForEpisode", null);
963
+ __decorate([
964
+ CaptureSpan(),
965
+ __metadata("design:type", Function),
966
+ __metadata("design:paramtypes", [ObjectID,
967
+ ObjectID,
968
+ Array,
969
+ Array, Boolean, Object]),
970
+ __metadata("design:returntype", Promise)
971
+ ], Service.prototype, "addOwners", null);
972
+ export default new Service();
973
+ //# sourceMappingURL=AlertEpisodeService.js.map