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