@oneuptime/common 12.0.7 → 12.0.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.
- package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +1 -1
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
- package/Models/DatabaseModels/AIConversation.ts +32 -0
- package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
- package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
- package/Models/DatabaseModels/Index.ts +12 -4
- package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +184 -9
- package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
- package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +33 -7
- package/Models/DatabaseModels/NetworkDevice.ts +141 -0
- package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
- package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
- package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
- package/Models/DatabaseModels/Project.ts +78 -0
- package/Models/DatabaseModels/UserCall.ts +42 -0
- package/Models/DatabaseModels/UserEmail.ts +44 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
- package/Models/DatabaseModels/UserPush.ts +49 -0
- package/Models/DatabaseModels/UserSMS.ts +43 -0
- package/Models/DatabaseModels/UserTelegram.ts +59 -0
- package/Models/DatabaseModels/UserWebhook.ts +52 -0
- package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
- package/Models/DatabaseModels/WorkflowLog.ts +38 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
- package/Server/API/AIChatAPI.ts +315 -1
- package/Server/API/DashboardAPI.ts +217 -1
- package/Server/API/OnCallReadinessAPI.ts +841 -0
- package/Server/API/TeamComplianceAPI.ts +69 -17
- package/Server/API/TelemetryAPI.ts +220 -12
- package/Server/API/UserAPI.ts +16 -1
- package/Server/EnvironmentConfig.ts +52 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +24 -0
- package/Server/Infrastructure/Queue.ts +78 -13
- package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
- package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
- package/Server/Services/AIService.ts +7 -0
- package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/AlertSeverityService.ts +63 -0
- package/Server/Services/DashboardService.ts +9 -10
- package/Server/Services/DatabaseService.ts +32 -2
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/IncidentSeverityService.ts +76 -0
- package/Server/Services/Index.ts +12 -4
- package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
- package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +7 -4
- package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +203 -21
- package/Server/Services/LogAggregationService.ts +45 -8
- package/Server/Services/MetricAggregationService.ts +121 -0
- package/Server/Services/MetricService.ts +7 -7
- package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
- package/Server/Services/NetworkDeviceLinkService.ts +84 -0
- package/Server/Services/NetworkDeviceService.ts +140 -0
- package/Server/Services/NetworkSiteService.ts +77 -25
- package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
- package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
- package/Server/Services/OnCallReadinessService.ts +2803 -0
- package/Server/Services/OnCallSetupReminderService.ts +955 -0
- package/Server/Services/ProfileAggregationService.ts +123 -0
- package/Server/Services/StatusPageService.ts +9 -10
- package/Server/Services/TeamComplianceService.ts +429 -252
- package/Server/Services/UserCallService.ts +26 -1
- package/Server/Services/UserEmailService.ts +26 -1
- package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
- package/Server/Services/UserNotificationRuleService.ts +3812 -333
- package/Server/Services/UserOnCallLogService.ts +561 -48
- package/Server/Services/UserPushService.ts +29 -0
- package/Server/Services/UserService.ts +11 -0
- package/Server/Services/UserSmsService.ts +26 -1
- package/Server/Services/UserTelegramService.ts +24 -1
- package/Server/Services/UserWebhookService.ts +28 -1
- package/Server/Services/UserWhatsAppService.ts +24 -1
- package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
- package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
- package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
- package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
- package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
- package/Server/Types/Workflow/Components/API/Get.ts +1 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
- package/Server/Types/Workflow/Components/API/Post.ts +1 -1
- package/Server/Types/Workflow/Components/API/Put.ts +1 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
- package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
- package/Server/Types/Workflow/Components/Email.ts +25 -7
- package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
- package/Server/Types/Workflow/TriggerCode.ts +12 -0
- package/Server/Types/Workflow/Workflow.ts +5 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
- package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
- package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
- package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
- package/Server/Utils/AI/Toolbox/Index.ts +48 -0
- package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
- package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
- package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
- package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
- package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
- package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
- package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
- package/Server/Utils/ClientIp.ts +221 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
- package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
- package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
- package/Server/Utils/Express.ts +12 -17
- package/Server/Utils/LLM/LLMService.ts +85 -8
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
- package/Server/Utils/SSRFProtection.ts +98 -23
- package/Server/Utils/StartServer.ts +12 -3
- package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
- package/Server/Utils/VM/VMAPI.ts +56 -8
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
- package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
- package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
- package/Tests/Models/InventoryItemModel.test.ts +174 -0
- package/Tests/Models/InventoryItemNaming.test.ts +302 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
- package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
- package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
- package/Tests/Server/API/Helpers.ts +24 -15
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
- package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
- package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
- package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
- package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
- package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
- package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +248 -0
- package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
- package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
- package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
- package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
- package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
- package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
- package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
- package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
- package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
- package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
- package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
- package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
- package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
- package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
- package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
- package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
- package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
- package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
- package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
- package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
- package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
- package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
- package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
- package/Tests/Server/Utils/ClientIp.test.ts +438 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
- package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
- package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
- package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
- package/Tests/Types/IP/IP.test.ts +263 -0
- package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
- package/Tests/Types/IP/IPv6.test.ts +12 -1
- package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
- package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
- package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
- package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
- package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
- package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +491 -0
- package/Tests/Types/Workflow/Templates.test.ts +1218 -0
- package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
- package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
- package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
- package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
- package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
- package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
- package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
- package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
- package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
- package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
- package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +893 -0
- package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +522 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +193 -0
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +388 -0
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +210 -0
- package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
- package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
- package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
- package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
- package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
- package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
- package/Tests/UI/EsbuildConfig.test.ts +607 -0
- package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
- package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
- package/Tests/UI/Utils/Platform.test.ts +147 -0
- package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +727 -0
- package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
- package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
- package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
- package/Tests/__mocks__/bullmq.js +55 -0
- package/Types/AI/AIChatMessageStatus.ts +8 -1
- package/Types/AI/AIChatTypes.ts +12 -0
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
- package/Types/Exception/ExceptionCode.ts +2 -0
- package/Types/Exception/ServiceUnavailableException.ts +8 -0
- package/Types/Exception/TooManyRequestsException.ts +8 -0
- package/Types/IP/IP.ts +93 -47
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +80 -3
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
- package/Types/OnCallDutyPolicy/Layer.ts +203 -149
- package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
- package/Types/Permission.ts +193 -0
- package/Types/SerializableObjectDictionary.ts +133 -39
- package/Types/Telemetry/EntityRelationshipType.ts +1 -1
- package/Types/Telemetry/EntitySource.ts +40 -0
- package/Types/Telemetry/EntityType.ts +28 -1
- package/Types/Telemetry/EntityTypeGroups.ts +65 -0
- package/Types/Workflow/Component.ts +29 -0
- package/Types/Workflow/Components/API.ts +35 -0
- package/Types/Workflow/Components/BaseModel.ts +77 -27
- package/Types/Workflow/Components/Discord.ts +1 -0
- package/Types/Workflow/Components/Email.ts +12 -3
- package/Types/Workflow/Components/JavaScript.ts +7 -0
- package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
- package/Types/Workflow/Components/Slack.ts +1 -0
- package/Types/Workflow/Components/Telegram.ts +1 -0
- package/Types/Workflow/StepTrace.ts +181 -0
- package/Types/Workflow/TemplateSyntax.ts +543 -0
- package/Types/Workflow/Templates.ts +2368 -0
- package/UI/Components/Calendar/Calendar.css +43 -0
- package/UI/Components/Calendar/Calendar.tsx +8 -0
- package/UI/Components/Card/Card.tsx +2 -2
- package/UI/Components/Checkbox/Checkbox.tsx +16 -0
- package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
- package/UI/Components/Dictionary/Dictionary.tsx +71 -15
- package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
- package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
- package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
- package/UI/Components/Forms/Types/Field.ts +7 -0
- package/UI/Components/Forms/Validation.ts +63 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
- package/UI/Components/Input/Input.tsx +32 -3
- package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
- package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
- package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
- package/UI/Components/LogsViewer/types.ts +23 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
- package/UI/Components/Modal/Modal.tsx +37 -4
- package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
- package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
- package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
- package/UI/Components/Table/Table.tsx +49 -16
- package/UI/Components/Table/TableBody.tsx +53 -28
- package/UI/Components/Table/TableHeader.tsx +13 -0
- package/UI/Components/Table/TableRow.tsx +58 -26
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
- package/UI/Components/Workflow/ArgumentsForm.tsx +341 -8
- package/UI/Components/Workflow/Component.tsx +28 -26
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +79 -9
- package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
- package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
- package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
- package/UI/Components/Workflow/GraphLint.ts +628 -0
- package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +528 -0
- package/UI/Components/Workflow/ModelSchema.ts +278 -0
- package/UI/Components/Workflow/RunForm.tsx +41 -7
- package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
- package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
- package/UI/Components/Workflow/UseRunWatch.ts +212 -0
- package/UI/Components/Workflow/Utils.ts +93 -1
- package/UI/Components/Workflow/VariableModal.tsx +6 -2
- package/UI/Components/Workflow/Workflow.tsx +126 -7
- package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
- package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
- package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
- package/UI/Types/LayeredDismissal.ts +31 -0
- package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
- package/UI/Utils/Platform.ts +149 -0
- package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
- package/UI/esbuild-config.js +22 -1
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +917 -155
- package/Utils/Telemetry/CrossSignalScope.ts +502 -0
- package/Utils/Telemetry/EntityKey.ts +71 -5
- package/Utils/Telemetry/EntityRelationship.ts +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +12 -4
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +212 -29
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
- package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +52 -25
- package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +80 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
- package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +237 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +165 -13
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
- package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
- package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +129 -18
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +16 -1
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +45 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +72 -13
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AIService.js +1 -0
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +54 -0
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/DashboardService.js +10 -9
- package/build/dist/Server/Services/DashboardService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +24 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +12 -4
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +9 -6
- package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +158 -23
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
- package/build/dist/Server/Services/LogAggregationService.js +27 -8
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +80 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +6 -6
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +53 -13
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
- package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
- package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
- package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +11 -10
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceService.js +312 -160
- package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +24 -1
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +24 -1
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
- package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +26 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +24 -1
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +22 -1
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +25 -1
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
- package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
- package/build/dist/Server/Utils/ClientIp.js +137 -0
- package/build/dist/Server/Utils/ClientIp.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
- package/build/dist/Server/Utils/Express.js +12 -12
- package/build/dist/Server/Utils/Express.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +82 -21
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +12 -4
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatTypes.js +12 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js +2 -0
- package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
- package/build/dist/Types/IP/IP.js +87 -43
- package/build/dist/Types/IP/IP.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/Permission.js +174 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +133 -39
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +39 -0
- package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +28 -1
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
- package/build/dist/Types/Workflow/Component.js +21 -0
- package/build/dist/Types/Workflow/Component.js.map +1 -1
- package/build/dist/Types/Workflow/Components/API.js +35 -0
- package/build/dist/Types/Workflow/Components/API.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +68 -26
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Discord.js +1 -0
- package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Email.js +12 -3
- package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
- package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Slack.js +1 -0
- package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
- package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
- package/build/dist/Types/Workflow/StepTrace.js +104 -0
- package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js +338 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +2111 -0
- package/build/dist/Types/Workflow/Templates.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js +47 -17
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +44 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +13 -4
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +31 -5
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +27 -15
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +24 -18
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +9 -1
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +29 -21
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +261 -14
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +20 -19
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +35 -7
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +425 -0
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +320 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js +156 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
- package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
- package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Utils.js +73 -1
- package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
- package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
- package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +92 -7
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
- package/build/dist/UI/Types/LayeredDismissal.js +21 -0
- package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Platform.js +118 -0
- package/build/dist/UI/Utils/Platform.js.map +1 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +661 -126
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +57 -5
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
- package/jest.config.json +1 -0
- package/package.json +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
|
@@ -0,0 +1,738 @@
|
|
|
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 DatabaseConfig from "../DatabaseConfig";
|
|
11
|
+
import GlobalCache from "../Infrastructure/GlobalCache";
|
|
12
|
+
import BaseService from "./BaseService";
|
|
13
|
+
import MailService from "./MailService";
|
|
14
|
+
import OnCallReadinessService, { ReadinessStatus, } from "./OnCallReadinessService";
|
|
15
|
+
import ProjectService from "./ProjectService";
|
|
16
|
+
import TeamMemberService from "./TeamMemberService";
|
|
17
|
+
import InProcessMemo from "../Utils/InProcessMemo";
|
|
18
|
+
import logger from "../Utils/Logger";
|
|
19
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
20
|
+
import URL from "../../Types/API/URL";
|
|
21
|
+
import Includes from "../../Types/BaseDatabase/Includes";
|
|
22
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
23
|
+
import Email from "../../Types/Email";
|
|
24
|
+
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
25
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
26
|
+
import NotificationRuleType from "../../Types/NotificationRule/NotificationRuleType";
|
|
27
|
+
import ObjectID from "../../Types/ObjectID";
|
|
28
|
+
/*
|
|
29
|
+
* "Ask these responders to finish their notification setup" - the one action on
|
|
30
|
+
* the readiness surfaces that reaches outside the product and touches a human.
|
|
31
|
+
*
|
|
32
|
+
* Phases 1-3 either rescue a page that was already going to be dropped or report
|
|
33
|
+
* a gap after it exists. This is the only piece that tries to stop the gap being
|
|
34
|
+
* there at all, and it works by mail because the fix is not the admin's to make:
|
|
35
|
+
* notification methods and notification rules live on the responder's own user
|
|
36
|
+
* record, and nobody - not an owner, not an admin - can add a phone number to
|
|
37
|
+
* somebody else's account and verify it for them. The most an admin can do is
|
|
38
|
+
* ask, so the product's job is to make the ask precise.
|
|
39
|
+
*
|
|
40
|
+
* PRECISE is the whole design. A generic "please check your on-call settings"
|
|
41
|
+
* nag is indistinguishable from every other automated mail an engineer deletes
|
|
42
|
+
* unread, and it teaches people that this sender is noise - which costs more
|
|
43
|
+
* than it saves, because the next mail from this system may be a page. So every
|
|
44
|
+
* reminder is built from that user's ACTUAL readiness, read fresh from
|
|
45
|
+
* OnCallReadinessService: it names the channels they never verified, or the
|
|
46
|
+
* severities with no rule, or the fact that nothing at all can reach them, and
|
|
47
|
+
* it links to the settings page where that specific thing is fixed.
|
|
48
|
+
*
|
|
49
|
+
* Four properties this file exists to guarantee, each of which was a way to get
|
|
50
|
+
* this wrong:
|
|
51
|
+
*
|
|
52
|
+
* 1. NEVER TRUST THE BODY. The caller hands over user ids. A user id is a user
|
|
53
|
+
* id whatever project it belongs to, and User is a GLOBAL model, so a
|
|
54
|
+
* request naming somebody in another project would otherwise mail a
|
|
55
|
+
* stranger about a project they have never heard of - with that project's
|
|
56
|
+
* name in it. Membership of the CALLER'S project is re-established here,
|
|
57
|
+
* inside the service that sends, not merely at the route.
|
|
58
|
+
*
|
|
59
|
+
* 2. ONE REMINDER PER (PROJECT, USER) PER 24 HOURS. Two admins looking at the
|
|
60
|
+
* same amber row, or one admin double-clicking, or a page storm driving
|
|
61
|
+
* somebody back to this screen every twenty minutes, must not become a mail
|
|
62
|
+
* storm. The window is claimed ATOMICALLY and cross-process (Redis SET NX),
|
|
63
|
+
* because a check-then-send would let two concurrent requests both observe
|
|
64
|
+
* "not reminded yet" and both send.
|
|
65
|
+
*
|
|
66
|
+
* 3. A BURNED WINDOW MUST BE EARNED. The claim happens BEFORE the send - that
|
|
67
|
+
* is what makes it a lock rather than a record - so a send that then fails
|
|
68
|
+
* would otherwise silence this person for a day over an SMTP blip. The
|
|
69
|
+
* claim is therefore RELEASED when the send fails, with a compare-and-
|
|
70
|
+
* delete so a release can only ever remove its own claim.
|
|
71
|
+
*
|
|
72
|
+
* 4. THE ANSWER IS PER USER, AND HONEST. "It worked" is not a truthful summary
|
|
73
|
+
* of eight sends where one address bounced and two were already reminded
|
|
74
|
+
* this morning. Every requested id comes back with its own outcome, and the
|
|
75
|
+
* UI is expected to say "5 sent, 2 skipped, 1 failed" rather than show a
|
|
76
|
+
* green tick. This service never reports Sent for a mail it did not
|
|
77
|
+
* observe leaving: MailService returns an HTTPErrorResponse rather than
|
|
78
|
+
* throwing for a non-200, so the status code is checked explicitly.
|
|
79
|
+
*/
|
|
80
|
+
/**
|
|
81
|
+
* What happened to ONE requested user. Every one of these is a distinct thing
|
|
82
|
+
* for the reader to do next, which is why they are not collapsed into a boolean:
|
|
83
|
+
*
|
|
84
|
+
* Sent - the mail left. Nothing more to do.
|
|
85
|
+
* SkippedThrottled - they were reminded inside the last 24h. Waiting is
|
|
86
|
+
* the correct action; sending again is not.
|
|
87
|
+
* SkippedNotAMember - the id is not in this project. Somebody is looking
|
|
88
|
+
* at a stale list, or at the wrong project.
|
|
89
|
+
* SkippedNothingMissing - they are Ready. There is nothing to remind them of,
|
|
90
|
+
* and a mail claiming otherwise would be a lie the
|
|
91
|
+
* recipient can immediately check.
|
|
92
|
+
* Failed - we tried and it did not go. Needs a human.
|
|
93
|
+
*/
|
|
94
|
+
export var SetupReminderOutcome;
|
|
95
|
+
(function (SetupReminderOutcome) {
|
|
96
|
+
SetupReminderOutcome["Sent"] = "Sent";
|
|
97
|
+
SetupReminderOutcome["SkippedThrottled"] = "SkippedThrottled";
|
|
98
|
+
SetupReminderOutcome["SkippedNotAMember"] = "SkippedNotAMember";
|
|
99
|
+
SetupReminderOutcome["SkippedNothingMissing"] = "SkippedNothingMissing";
|
|
100
|
+
SetupReminderOutcome["Failed"] = "Failed";
|
|
101
|
+
})(SetupReminderOutcome || (SetupReminderOutcome = {}));
|
|
102
|
+
/*
|
|
103
|
+
* A ceiling on one request, REFUSED rather than clamped.
|
|
104
|
+
*
|
|
105
|
+
* This is a mail-sending endpoint reachable by any project member, so an
|
|
106
|
+
* unbounded id list is a mail cannon with an HTTP interface. It is also a
|
|
107
|
+
* fan-out of one HTTP call per recipient into the notification service, so a
|
|
108
|
+
* five-thousand-id body would hold a request open for minutes.
|
|
109
|
+
*
|
|
110
|
+
* Refusing rather than truncating follows the same rule as the paging on the
|
|
111
|
+
* readiness routes: a caller who asked to remind 900 people and is silently told
|
|
112
|
+
* "done" about the first 250 has been actively misled about the other 650. The
|
|
113
|
+
* error names the ceiling so the caller can split the list themselves.
|
|
114
|
+
*/
|
|
115
|
+
export const SETUP_REMINDER_MAX_RECIPIENTS = 250;
|
|
116
|
+
/*
|
|
117
|
+
* The quiet period, in the two units the two throttle layers want it in.
|
|
118
|
+
*
|
|
119
|
+
* 24 hours is chosen to match OnCallNotificationAlertingService's window rather
|
|
120
|
+
* than for any reason of its own: a responder with no rules is liable to receive
|
|
121
|
+
* BOTH mails - the automatic "you were paged without a rule" one and this
|
|
122
|
+
* deliberate "please set yourself up" one - and two systems reminding the same
|
|
123
|
+
* person about the same gap on two different clocks is how a useful signal turns
|
|
124
|
+
* into noise.
|
|
125
|
+
*/
|
|
126
|
+
const REMINDER_WINDOW_IN_SECONDS = 24 * 60 * 60;
|
|
127
|
+
const REMINDER_WINDOW_IN_MS = REMINDER_WINDOW_IN_SECONDS * 1000;
|
|
128
|
+
/*
|
|
129
|
+
* The Redis namespace for the throttle. Distinct from anything the readiness
|
|
130
|
+
* CACHE uses: a readiness cache entry is a performance detail that may be
|
|
131
|
+
* dropped at any moment (the Recheck button does exactly that), whereas dropping
|
|
132
|
+
* a throttle key re-arms a mail. Sharing a namespace would let a cache flush
|
|
133
|
+
* become a mail storm.
|
|
134
|
+
*/
|
|
135
|
+
const REMINDER_THROTTLE_NAMESPACE = "oncall-setup-reminder";
|
|
136
|
+
/*
|
|
137
|
+
* Bounded so the in-process half of the throttle cannot become a memory leak on
|
|
138
|
+
* a large install. An evicted key costs at most one extra mail, and only when
|
|
139
|
+
* Redis is also unavailable - the Redis fence is what actually enforces the
|
|
140
|
+
* window.
|
|
141
|
+
*/
|
|
142
|
+
const THROTTLE_MAX_ENTRIES = 10000;
|
|
143
|
+
/*
|
|
144
|
+
* Dashboard user-settings path segments, duplicated from the Dashboard's
|
|
145
|
+
* UserSettingsRoutePath.
|
|
146
|
+
*
|
|
147
|
+
* Common/Server cannot import App sources, which is why
|
|
148
|
+
* OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard and
|
|
149
|
+
* OnCallNotificationAlertingService both spell their routes out by hand too. The
|
|
150
|
+
* duplication is a known cost; sending somebody a link to the wrong settings tab
|
|
151
|
+
* is a worse one, because a reminder that lands on a page with nothing wrong on
|
|
152
|
+
* it reads as "this system is confused" and gets ignored.
|
|
153
|
+
*/
|
|
154
|
+
const NOTIFICATION_METHODS_PATH = "notification-methods";
|
|
155
|
+
const INCIDENT_RULES_PATH = "incident-on-call-rules";
|
|
156
|
+
const INCIDENT_EPISODE_RULES_PATH = "incident-episode-on-call-rules";
|
|
157
|
+
const ALERT_RULES_PATH = "alert-on-call-rules";
|
|
158
|
+
const ALERT_EPISODE_RULES_PATH = "alert-episode-on-call-rules";
|
|
159
|
+
/*
|
|
160
|
+
* How many reason lines a reminder carries before it stops listing them.
|
|
161
|
+
*
|
|
162
|
+
* A project with eight incident severities and eight alert severities and a
|
|
163
|
+
* responder with no rules at all produces one line per rule type, which is
|
|
164
|
+
* short - but the reasons are generated prose and this is a mail nobody is
|
|
165
|
+
* obliged to read. Anything past this is summarised rather than printed, so the
|
|
166
|
+
* message stays scannable and the call to action stays above the fold.
|
|
167
|
+
*/
|
|
168
|
+
const MAX_REASON_LINES = 6;
|
|
169
|
+
/*
|
|
170
|
+
* The outcome of trying to take the 24h window for one (project, user).
|
|
171
|
+
*
|
|
172
|
+
* Only two states, deliberately: a caller that cannot claim must not send, and a
|
|
173
|
+
* caller that cannot reach Redis must still be able to (see claimReminderWindow
|
|
174
|
+
* for why "cache is down" resolves to Claimed rather than to a third state the
|
|
175
|
+
* send path would have to branch on).
|
|
176
|
+
*/
|
|
177
|
+
var ThrottleClaim;
|
|
178
|
+
(function (ThrottleClaim) {
|
|
179
|
+
ThrottleClaim["Claimed"] = "Claimed";
|
|
180
|
+
ThrottleClaim["AlreadyReminded"] = "AlreadyReminded";
|
|
181
|
+
})(ThrottleClaim || (ThrottleClaim = {}));
|
|
182
|
+
export class OnCallSetupReminderService extends BaseService {
|
|
183
|
+
constructor() {
|
|
184
|
+
super(...arguments);
|
|
185
|
+
/*
|
|
186
|
+
* The in-process half of the throttle - an L1 in front of Redis, not a
|
|
187
|
+
* replacement for it.
|
|
188
|
+
*
|
|
189
|
+
* Redis is what actually enforces "once per 24h", because it is the only layer
|
|
190
|
+
* that is both atomic and shared. This map exists so that the common shape of
|
|
191
|
+
* the mistake - one admin, one screen, several clicks - is answered without a
|
|
192
|
+
* network round trip per recipient per click, and so that the feature degrades
|
|
193
|
+
* to SOMETHING rather than to nothing when the cache is unreachable.
|
|
194
|
+
*/
|
|
195
|
+
this.localThrottle = new InProcessMemo({
|
|
196
|
+
ttlInMs: REMINDER_WINDOW_IN_MS,
|
|
197
|
+
maxEntries: THROTTLE_MAX_ENTRIES,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Mail every named user about what is missing from their own on-call setup,
|
|
202
|
+
* and report per user what actually happened.
|
|
203
|
+
*
|
|
204
|
+
* Throws only for a request that is wrong as a whole - no ids, too many ids, a
|
|
205
|
+
* project that does not exist. Anything that is wrong about ONE user comes
|
|
206
|
+
* back as that user's outcome, because a single departed team member on a list
|
|
207
|
+
* of thirty must not cancel the other twenty-nine reminders. That asymmetry is
|
|
208
|
+
* the entire reason this returns a per-user array rather than void.
|
|
209
|
+
*
|
|
210
|
+
* The caller is responsible for having established that the requester may act
|
|
211
|
+
* on `projectId` at all; this service re-checks that each USER belongs to it,
|
|
212
|
+
* which is the half the route cannot do without duplicating the readiness
|
|
213
|
+
* read.
|
|
214
|
+
*/
|
|
215
|
+
async sendSetupReminders(data) {
|
|
216
|
+
/*
|
|
217
|
+
* De-duplicated before anything else. A list with the same id twice is one
|
|
218
|
+
* person, and the throttle would catch the second copy anyway - but it would
|
|
219
|
+
* catch it as "skipped, reminded in the last 24 hours", which reads to an
|
|
220
|
+
* admin as though somebody else had already got there rather than as their
|
|
221
|
+
* own list containing a duplicate.
|
|
222
|
+
*/
|
|
223
|
+
const requestedUserIds = this.distinctIds(data.userIds);
|
|
224
|
+
if (requestedUserIds.length === 0) {
|
|
225
|
+
throw new BadDataException("Select at least one responder to send a setup reminder to.");
|
|
226
|
+
}
|
|
227
|
+
if (requestedUserIds.length > SETUP_REMINDER_MAX_RECIPIENTS) {
|
|
228
|
+
throw new BadDataException(`A setup reminder can be sent to at most ${SETUP_REMINDER_MAX_RECIPIENTS} responders at a time. Received ${requestedUserIds.length}. Send the rest in a second batch.`);
|
|
229
|
+
}
|
|
230
|
+
const project = await ProjectService.findOneById({
|
|
231
|
+
id: data.projectId,
|
|
232
|
+
select: {
|
|
233
|
+
_id: true,
|
|
234
|
+
name: true,
|
|
235
|
+
},
|
|
236
|
+
props: {
|
|
237
|
+
isRoot: true,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
/*
|
|
241
|
+
* The caller was already authorised against this project, so a missing row
|
|
242
|
+
* here is not a permissions question - it is a project that has been deleted
|
|
243
|
+
* underneath an open tab. Failing the whole request is right: every mail
|
|
244
|
+
* this request would send names the project, and "your project" is not a
|
|
245
|
+
* sentence worth mailing anybody.
|
|
246
|
+
*/
|
|
247
|
+
if (!project) {
|
|
248
|
+
throw new BadDataException("Project not found.");
|
|
249
|
+
}
|
|
250
|
+
/*
|
|
251
|
+
* One batched readiness read for the whole set - the service's own contract
|
|
252
|
+
* is that the query count does not grow with the number of users - and it is
|
|
253
|
+
* ALSO the membership check for everyone it answers for: getReadinessForUsers
|
|
254
|
+
* omits users who are not members of the project.
|
|
255
|
+
*/
|
|
256
|
+
const readinessList = await OnCallReadinessService.getReadinessForUsers(requestedUserIds, data.projectId);
|
|
257
|
+
const readinessByUserId = new Map();
|
|
258
|
+
for (const readiness of readinessList) {
|
|
259
|
+
readinessByUserId.set(readiness.userId.toString(), readiness);
|
|
260
|
+
}
|
|
261
|
+
/*
|
|
262
|
+
* Everyone the readiness read did not answer for. Usually empty, which is
|
|
263
|
+
* why the follow-up query below is conditional: this is the only place the
|
|
264
|
+
* two ways of getting nothing back are told apart, and they are told apart
|
|
265
|
+
* because the two sentences an admin needs are completely different -
|
|
266
|
+
* "that person is not in this project" is a list they should fix, and "we
|
|
267
|
+
* could not work out what they are missing" is a bug they should report.
|
|
268
|
+
*/
|
|
269
|
+
const unresolvedUserIds = requestedUserIds.filter((userId) => {
|
|
270
|
+
return !readinessByUserId.has(userId.toString());
|
|
271
|
+
});
|
|
272
|
+
const unresolvedButMemberIds = await this.findMembersAmong(data.projectId, unresolvedUserIds);
|
|
273
|
+
const context = {
|
|
274
|
+
projectId: data.projectId,
|
|
275
|
+
projectName: project.name || "",
|
|
276
|
+
dashboardUrl: await DatabaseConfig.getDashboardUrl(),
|
|
277
|
+
};
|
|
278
|
+
const results = [];
|
|
279
|
+
/*
|
|
280
|
+
* Sequential rather than Promise.all, and that is a decision rather than an
|
|
281
|
+
* oversight. Each iteration is a Redis round trip and an HTTP call into the
|
|
282
|
+
* notification service; firing 250 of those at once is a self-inflicted
|
|
283
|
+
* thundering herd against the mail path, on a request whose latency nobody
|
|
284
|
+
* is watching a spinner for at millisecond resolution. Sequential also keeps
|
|
285
|
+
* `results` in the caller's own order, so the UI can line outcomes up
|
|
286
|
+
* against the rows the admin ticked.
|
|
287
|
+
*/
|
|
288
|
+
for (const userId of requestedUserIds) {
|
|
289
|
+
results.push(await this.remindOneUser({
|
|
290
|
+
context: context,
|
|
291
|
+
userId: userId,
|
|
292
|
+
readiness: readinessByUserId.get(userId.toString()),
|
|
293
|
+
isMemberWithoutReadiness: unresolvedButMemberIds.has(userId.toString()),
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
return this.tally(data.projectId, requestedUserIds.length, results);
|
|
297
|
+
}
|
|
298
|
+
/*
|
|
299
|
+
* One user, start to finish. Never throws: every failure is an outcome, so one
|
|
300
|
+
* bad recipient cannot take the batch down with it.
|
|
301
|
+
*/
|
|
302
|
+
async remindOneUser(input) {
|
|
303
|
+
const { context, userId, readiness, isMemberWithoutReadiness } = input;
|
|
304
|
+
if (!readiness) {
|
|
305
|
+
if (isMemberWithoutReadiness) {
|
|
306
|
+
logger.error(`OnCallSetupReminderService: user ${userId.toString()} is a member of project ${context.projectId.toString()} but readiness could not be computed for them, so no setup reminder was sent.`);
|
|
307
|
+
return {
|
|
308
|
+
userId: userId,
|
|
309
|
+
outcome: SetupReminderOutcome.Failed,
|
|
310
|
+
message: "We could not work out what this responder is missing, so nothing was sent.",
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
userId: userId,
|
|
315
|
+
outcome: SetupReminderOutcome.SkippedNotAMember,
|
|
316
|
+
message: "Not a member of this project - no reminder was sent. Refresh the page; this list may be out of date.",
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/*
|
|
320
|
+
* A Ready responder has nothing to be reminded of, and telling them
|
|
321
|
+
* otherwise is not a harmless nudge: it is a mail from the on-call system
|
|
322
|
+
* making a factual claim they can check in ten seconds and find false. Do
|
|
323
|
+
* that twice and the next mail from this sender - which might be the one
|
|
324
|
+
* that matters - has already been filed as noise.
|
|
325
|
+
*/
|
|
326
|
+
if (readiness.status === ReadinessStatus.Ready) {
|
|
327
|
+
return {
|
|
328
|
+
userId: userId,
|
|
329
|
+
outcome: SetupReminderOutcome.SkippedNothingMissing,
|
|
330
|
+
message: "Already ready - nothing is missing, so there was nothing to remind them about.",
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/*
|
|
334
|
+
* The account email, which is the only address we can reach somebody at
|
|
335
|
+
* before they have set anything up - their notification methods are, by
|
|
336
|
+
* definition, the thing that is missing. An account with no usable email is
|
|
337
|
+
* a genuine dead end and is reported as one rather than quietly dropped.
|
|
338
|
+
*/
|
|
339
|
+
if (!readiness.userEmail || !Email.isValid(readiness.userEmail)) {
|
|
340
|
+
logger.error(`OnCallSetupReminderService: user ${userId.toString()} in project ${context.projectId.toString()} has no usable account email, so no setup reminder could be sent.`);
|
|
341
|
+
return {
|
|
342
|
+
userId: userId,
|
|
343
|
+
outcome: SetupReminderOutcome.Failed,
|
|
344
|
+
message: "This responder has no usable account email address, so there is nowhere to send a reminder.",
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/*
|
|
348
|
+
* A token unique to THIS attempt. It is what makes the release safe: a
|
|
349
|
+
* compare-and-delete can then only ever remove the claim this attempt made,
|
|
350
|
+
* so a slow failing send that releases after its window has already expired
|
|
351
|
+
* and been re-taken by somebody else cannot delete the new holder's claim.
|
|
352
|
+
*/
|
|
353
|
+
const token = ObjectID.generate().toString();
|
|
354
|
+
const claim = await this.claimReminderWindow({
|
|
355
|
+
projectId: context.projectId,
|
|
356
|
+
userId: userId,
|
|
357
|
+
token: token,
|
|
358
|
+
});
|
|
359
|
+
if (claim === ThrottleClaim.AlreadyReminded) {
|
|
360
|
+
return {
|
|
361
|
+
userId: userId,
|
|
362
|
+
outcome: SetupReminderOutcome.SkippedThrottled,
|
|
363
|
+
message: "Already reminded in the last 24 hours - skipped so repeated clicks cannot turn into a mail storm.",
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
try {
|
|
367
|
+
const response = await MailService.sendMail({
|
|
368
|
+
toEmail: new Email(readiness.userEmail),
|
|
369
|
+
templateType: EmailTemplateType.SimpleMessage,
|
|
370
|
+
vars: this.buildTemplateVars(context, readiness),
|
|
371
|
+
subject: this.buildSubject(context, readiness),
|
|
372
|
+
}, {
|
|
373
|
+
projectId: context.projectId,
|
|
374
|
+
userId: userId,
|
|
375
|
+
});
|
|
376
|
+
/*
|
|
377
|
+
* MailService goes through API.post, which RESOLVES with an
|
|
378
|
+
* HTTPErrorResponse for a non-2xx rather than throwing - so a try/catch on
|
|
379
|
+
* its own would report Sent for a mail the notification service refused.
|
|
380
|
+
* That is precisely the "green tick over nothing" this phase exists to
|
|
381
|
+
* remove, so the status is checked explicitly and a failure falls through
|
|
382
|
+
* to the same release-and-report path as a thrown error.
|
|
383
|
+
*/
|
|
384
|
+
if (response.isFailure()) {
|
|
385
|
+
throw new Error(`The notification service answered ${response.statusCode}.`);
|
|
386
|
+
}
|
|
387
|
+
/*
|
|
388
|
+
* Stamped only after the send is known to have left. Stamping earlier
|
|
389
|
+
* would make the local memo disagree with the Redis claim we are about to
|
|
390
|
+
* release on failure, and this process would then refuse to retry for a
|
|
391
|
+
* day over a mail that never went.
|
|
392
|
+
*/
|
|
393
|
+
this.localThrottle.set(this.getThrottleKey(context.projectId, userId), true);
|
|
394
|
+
return {
|
|
395
|
+
userId: userId,
|
|
396
|
+
outcome: SetupReminderOutcome.Sent,
|
|
397
|
+
message: "Reminder sent to their account email address.",
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
catch (err) {
|
|
401
|
+
logger.error(`OnCallSetupReminderService: failed to send a setup reminder to user ${userId.toString()} in project ${context.projectId.toString()}.`);
|
|
402
|
+
logger.error(err);
|
|
403
|
+
/*
|
|
404
|
+
* Give the window back. The claim was taken to stop a SECOND mail, and no
|
|
405
|
+
* first mail happened - keeping it would silence this responder for a day
|
|
406
|
+
* because of an SMTP hiccup, which is the failure mode of every throttle
|
|
407
|
+
* that records intent instead of outcome.
|
|
408
|
+
*/
|
|
409
|
+
await this.releaseReminderWindow({
|
|
410
|
+
projectId: context.projectId,
|
|
411
|
+
userId: userId,
|
|
412
|
+
token: token,
|
|
413
|
+
});
|
|
414
|
+
return {
|
|
415
|
+
userId: userId,
|
|
416
|
+
outcome: SetupReminderOutcome.Failed,
|
|
417
|
+
message: "We could not send this reminder. Nothing was delivered - try again, and check the notification settings for this install if it keeps failing.",
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/*
|
|
422
|
+
* Take the 24h window, atomically and across every pod.
|
|
423
|
+
*
|
|
424
|
+
* SET NX is what makes this a lock rather than a note. A GET-then-SET would
|
|
425
|
+
* let two concurrent requests - two admins on the same screen, or one admin's
|
|
426
|
+
* double-click arriving on two replicas - both observe "not reminded yet" and
|
|
427
|
+
* both send, which is exactly the duplicate this exists to prevent and exactly
|
|
428
|
+
* the race that is impossible to reproduce when somebody reports it.
|
|
429
|
+
*
|
|
430
|
+
* When the cache is unreachable this resolves to Claimed - it FAILS OPEN. The
|
|
431
|
+
* alternative is refusing to send, and a feature that silently stops working
|
|
432
|
+
* whenever Redis blips is worse than one that occasionally sends a second copy
|
|
433
|
+
* of a mail somebody asked for: the local memo still catches the repeat click
|
|
434
|
+
* that produced nearly all of the duplicates this guards against, and the cost
|
|
435
|
+
* of being wrong is one extra email rather than a responder who never hears
|
|
436
|
+
* that nothing can page them.
|
|
437
|
+
*/
|
|
438
|
+
async claimReminderWindow(data) {
|
|
439
|
+
const key = this.getThrottleKey(data.projectId, data.userId);
|
|
440
|
+
if (this.localThrottle.get(key)) {
|
|
441
|
+
return ThrottleClaim.AlreadyReminded;
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
const claimed = await GlobalCache.setStringIfNotExists(REMINDER_THROTTLE_NAMESPACE, key, data.token, {
|
|
445
|
+
expiresInSeconds: REMINDER_WINDOW_IN_SECONDS,
|
|
446
|
+
});
|
|
447
|
+
if (!claimed) {
|
|
448
|
+
/*
|
|
449
|
+
* Somebody else holds the window - another pod, or this one before a
|
|
450
|
+
* restart. Recorded locally too so the rest of this batch, and the next
|
|
451
|
+
* few clicks, are answered without a round trip each.
|
|
452
|
+
*
|
|
453
|
+
* The local TTL is deliberately the FULL window rather than whatever is
|
|
454
|
+
* left of the Redis key's. It can therefore stay set for slightly longer
|
|
455
|
+
* than the real quiet period, which errs towards one fewer mail - the
|
|
456
|
+
* safe direction for a throttle, and invisible next to a 24h window.
|
|
457
|
+
*/
|
|
458
|
+
this.localThrottle.set(key, true);
|
|
459
|
+
return ThrottleClaim.AlreadyReminded;
|
|
460
|
+
}
|
|
461
|
+
return ThrottleClaim.Claimed;
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
logger.warn(`OnCallSetupReminderService: the shared cache is unavailable, so the 24h setup-reminder throttle for project ${data.projectId.toString()} is enforced within this process only. A duplicate reminder is possible across pods.`);
|
|
465
|
+
logger.warn(err);
|
|
466
|
+
return ThrottleClaim.Claimed;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/*
|
|
470
|
+
* Hand the window back after a send that did not happen. Compare-and-delete,
|
|
471
|
+
* so this can only ever remove the claim its own attempt made.
|
|
472
|
+
*
|
|
473
|
+
* Best effort by construction: the send has already failed and is already
|
|
474
|
+
* being reported as failed, and a cache that cannot be reached to release a
|
|
475
|
+
* key costs at most a 24h delay before this responder can be reminded again.
|
|
476
|
+
* Turning that into a second error would replace an honest "failed" with an
|
|
477
|
+
* exception nobody can act on.
|
|
478
|
+
*/
|
|
479
|
+
async releaseReminderWindow(data) {
|
|
480
|
+
try {
|
|
481
|
+
await GlobalCache.deleteKeyIfValue(REMINDER_THROTTLE_NAMESPACE, this.getThrottleKey(data.projectId, data.userId), data.token);
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
logger.warn(`OnCallSetupReminderService: could not release the setup-reminder throttle for user ${data.userId.toString()} in project ${data.projectId.toString()} after a failed send. They cannot be reminded again for up to 24 hours.`);
|
|
485
|
+
logger.warn(err);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/*
|
|
489
|
+
* Which of these ids are members of the project after all.
|
|
490
|
+
*
|
|
491
|
+
* Only ever called with the ids the readiness read did NOT answer for, which
|
|
492
|
+
* is normally none - so this is normally zero queries. Those ids are by
|
|
493
|
+
* construction either non-members (no rows at all) or the rare member whose
|
|
494
|
+
* User row has gone, so the result set is tiny and a single unpaged read is
|
|
495
|
+
* safe here in a way it would not be for the whole requested set.
|
|
496
|
+
*
|
|
497
|
+
* TeamMember is the membership table for a project - even the creating owner
|
|
498
|
+
* gets a row - so its absence is a definitive "not in this project".
|
|
499
|
+
* Invitation state is deliberately not part of the query, matching
|
|
500
|
+
* OnCallReadinessService and OnCallReadinessAPI: somebody with a pending
|
|
501
|
+
* invitation can already be sitting on an escalation rule, and they are
|
|
502
|
+
* exactly the person most likely to have set nothing up.
|
|
503
|
+
*/
|
|
504
|
+
async findMembersAmong(projectId, userIds) {
|
|
505
|
+
const memberIds = new Set();
|
|
506
|
+
if (userIds.length === 0) {
|
|
507
|
+
return memberIds;
|
|
508
|
+
}
|
|
509
|
+
const memberships = await TeamMemberService.findBy({
|
|
510
|
+
query: {
|
|
511
|
+
projectId: projectId,
|
|
512
|
+
userId: new Includes(userIds),
|
|
513
|
+
},
|
|
514
|
+
select: {
|
|
515
|
+
_id: true,
|
|
516
|
+
userId: true,
|
|
517
|
+
},
|
|
518
|
+
limit: LIMIT_PER_PROJECT,
|
|
519
|
+
skip: 0,
|
|
520
|
+
props: {
|
|
521
|
+
isRoot: true,
|
|
522
|
+
},
|
|
523
|
+
});
|
|
524
|
+
for (const membership of memberships) {
|
|
525
|
+
if (membership.userId) {
|
|
526
|
+
memberIds.add(membership.userId.toString());
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return memberIds;
|
|
530
|
+
}
|
|
531
|
+
/*
|
|
532
|
+
* The subject line, which is most of whether this gets opened at all.
|
|
533
|
+
*
|
|
534
|
+
* Two of them, because the two statuses are two different messages: one person
|
|
535
|
+
* cannot be paged at all and the other can, just not the way they asked. A
|
|
536
|
+
* single subject covering both would have to be vague enough to describe
|
|
537
|
+
* neither.
|
|
538
|
+
*
|
|
539
|
+
* NOT escaped. The subject is rendered through {{title}} in EmailTitle.hbs,
|
|
540
|
+
* which Handlebars escapes for us, and the same string is used verbatim as the
|
|
541
|
+
* SMTP subject header - escaping here would double-escape the first and
|
|
542
|
+
* corrupt the second. Escaped values belong in the message body only.
|
|
543
|
+
*/
|
|
544
|
+
buildSubject(context, readiness) {
|
|
545
|
+
const projectName = context.projectName || "your project";
|
|
546
|
+
if (readiness.status === ReadinessStatus.NotReachable) {
|
|
547
|
+
return `Action needed: nothing can page you in ${projectName}`;
|
|
548
|
+
}
|
|
549
|
+
return `Finish your on-call notification setup in ${projectName}`;
|
|
550
|
+
}
|
|
551
|
+
/*
|
|
552
|
+
* The Handlebars vars for SimpleMessage.hbs.
|
|
553
|
+
*
|
|
554
|
+
* SimpleMessage renders `message` through InfoBlock, which uses a TRIPLE
|
|
555
|
+
* stache ({{{info}}}) - i.e. raw HTML, no escaping anywhere between here and
|
|
556
|
+
* the recipient's inbox. Every value that came from a database column is
|
|
557
|
+
* therefore escaped on the way in: the project name is typed by an admin, and
|
|
558
|
+
* the reason sentences carry severity names typed by an admin too. The only
|
|
559
|
+
* unescaped markup is the fixed structure this method writes itself.
|
|
560
|
+
*/
|
|
561
|
+
buildTemplateVars(context, readiness) {
|
|
562
|
+
const subject = this.buildSubject(context, readiness);
|
|
563
|
+
return {
|
|
564
|
+
subject: subject,
|
|
565
|
+
message: this.buildMessageHtml(context, readiness),
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
buildMessageHtml(context, readiness) {
|
|
569
|
+
const projectName = this.escapeHtml(context.projectName || "your project");
|
|
570
|
+
/*
|
|
571
|
+
* Whether they are actually on a rotation right now changes the first
|
|
572
|
+
* sentence, and the first sentence is the whole justification for the mail.
|
|
573
|
+
* "You are on an on-call rotation and cannot be paged" is urgent and true
|
|
574
|
+
* for a responder some policy reaches; said to somebody who is on no policy
|
|
575
|
+
* at all it is simply false, and a reminder that opens with something the
|
|
576
|
+
* reader knows to be untrue has spent its credibility in one line.
|
|
577
|
+
*/
|
|
578
|
+
const isOnRotation = readiness.reachedVia.length > 0;
|
|
579
|
+
const lines = [];
|
|
580
|
+
if (readiness.status === ReadinessStatus.NotReachable) {
|
|
581
|
+
lines.push(isOnRotation
|
|
582
|
+
? `You are on an on-call rotation in ${projectName}, and right now there is no way for us to page you. If an incident is routed to you, it reaches nobody and the escalation simply runs down.`
|
|
583
|
+
: `You are a member of ${projectName} and can be added to an on-call rotation at any time. Right now there is no way for us to page you at all.`);
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
lines.push(isOnRotation
|
|
587
|
+
? `You are on an on-call rotation in ${projectName}. We can reach you, but not for everything - some pages have no notification rule of yours to follow.`
|
|
588
|
+
: `You are a member of ${projectName} and can be added to an on-call rotation at any time. Some pages would have no notification rule of yours to follow.`);
|
|
589
|
+
}
|
|
590
|
+
lines.push(this.buildReasonListHtml(readiness));
|
|
591
|
+
const settingsLink = this.escapeHtml(this.getSettingsLink(context, readiness).toString());
|
|
592
|
+
lines.push(`Only you can change this - notification methods and on-call rules live on your own account, so nobody in ${projectName} can set them up for you: <a href="${settingsLink}">${settingsLink}</a>`);
|
|
593
|
+
lines.push(`An administrator of ${projectName} asked us to send you this. You will not get another copy for at least 24 hours.`);
|
|
594
|
+
return lines.join("<br/><br/>");
|
|
595
|
+
}
|
|
596
|
+
/*
|
|
597
|
+
* The gap itself, as a list rather than a paragraph.
|
|
598
|
+
*
|
|
599
|
+
* These sentences are OnCallReadinessService's own `reasons`, verbatim, and
|
|
600
|
+
* that is the point: the mail, the readiness table and the policy card all say
|
|
601
|
+
* the same words about the same person, so an admin who forwards this to a
|
|
602
|
+
* responder is not explaining a second vocabulary. Escaped one at a time,
|
|
603
|
+
* because a reason embeds severity names an admin typed.
|
|
604
|
+
*/
|
|
605
|
+
buildReasonListHtml(readiness) {
|
|
606
|
+
const reasons = readiness.reasons;
|
|
607
|
+
if (reasons.length === 0) {
|
|
608
|
+
/*
|
|
609
|
+
* Not reachable from a non-Ready status today - every such status
|
|
610
|
+
* produces at least one reason - but a mail with a "here is what is
|
|
611
|
+
* missing" heading and nothing under it would be worse than a slightly
|
|
612
|
+
* vaguer sentence, so the degenerate case gets prose instead of an empty
|
|
613
|
+
* bullet list.
|
|
614
|
+
*/
|
|
615
|
+
return `Your notification setup in this project is incomplete. Open your settings to see what is missing.`;
|
|
616
|
+
}
|
|
617
|
+
const shown = reasons.slice(0, MAX_REASON_LINES);
|
|
618
|
+
const items = shown
|
|
619
|
+
.map((reason) => {
|
|
620
|
+
return `<li>${this.escapeHtml(reason)}</li>`;
|
|
621
|
+
})
|
|
622
|
+
.join("");
|
|
623
|
+
const remaining = reasons.length - shown.length;
|
|
624
|
+
const more = remaining > 0
|
|
625
|
+
? `<li>and ${remaining} more, listed in your settings</li>`
|
|
626
|
+
: "";
|
|
627
|
+
return `Here is what is missing:<ul>${items}${more}</ul>`;
|
|
628
|
+
}
|
|
629
|
+
/*
|
|
630
|
+
* The deep link, chosen by what is actually wrong.
|
|
631
|
+
*
|
|
632
|
+
* A responder nothing can reach needs Notification Methods - adding a rule
|
|
633
|
+
* would change nothing while there is no verified channel to deliver it on.
|
|
634
|
+
* A responder who IS reachable but has holes needs the on-call rules page for
|
|
635
|
+
* the rule type of their first hole. Sending either of them to the other's
|
|
636
|
+
* page produces a screen where nothing looks wrong, which is how a reminder
|
|
637
|
+
* gets classified as a false alarm.
|
|
638
|
+
*/
|
|
639
|
+
getSettingsLink(context, readiness) {
|
|
640
|
+
return URL.fromString(context.dashboardUrl.toString()).addRoute(`/${context.projectId.toString()}/user-settings/${this.getSettingsPath(readiness)}`);
|
|
641
|
+
}
|
|
642
|
+
getSettingsPath(readiness) {
|
|
643
|
+
if (readiness.status === ReadinessStatus.NotReachable) {
|
|
644
|
+
return NOTIFICATION_METHODS_PATH;
|
|
645
|
+
}
|
|
646
|
+
const firstGap = readiness.coverage.find((cell) => {
|
|
647
|
+
return !cell.hasRule && !cell.isOptOut;
|
|
648
|
+
});
|
|
649
|
+
if (!firstGap) {
|
|
650
|
+
return NOTIFICATION_METHODS_PATH;
|
|
651
|
+
}
|
|
652
|
+
switch (firstGap.ruleType) {
|
|
653
|
+
case NotificationRuleType.ON_CALL_EXECUTED_ALERT:
|
|
654
|
+
return ALERT_RULES_PATH;
|
|
655
|
+
case NotificationRuleType.ON_CALL_EXECUTED_ALERT_EPISODE:
|
|
656
|
+
return ALERT_EPISODE_RULES_PATH;
|
|
657
|
+
case NotificationRuleType.ON_CALL_EXECUTED_INCIDENT_EPISODE:
|
|
658
|
+
return INCIDENT_EPISODE_RULES_PATH;
|
|
659
|
+
case NotificationRuleType.ON_CALL_EXECUTED_INCIDENT:
|
|
660
|
+
case NotificationRuleType.WHEN_USER_GOES_ON_CALL:
|
|
661
|
+
case NotificationRuleType.WHEN_USER_GOES_OFF_CALL:
|
|
662
|
+
return INCIDENT_RULES_PATH;
|
|
663
|
+
default:
|
|
664
|
+
/*
|
|
665
|
+
* A rule type this build has not heard of. Notification Methods is the
|
|
666
|
+
* one page that is relevant to every gap there could ever be, so an
|
|
667
|
+
* unknown type degrades to "somewhere useful" rather than to a guess
|
|
668
|
+
* about which settings tab it belongs on.
|
|
669
|
+
*/
|
|
670
|
+
return NOTIFICATION_METHODS_PATH;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
tally(projectId, requestedCount, results) {
|
|
674
|
+
let sentCount = 0;
|
|
675
|
+
let skippedCount = 0;
|
|
676
|
+
let failedCount = 0;
|
|
677
|
+
for (const result of results) {
|
|
678
|
+
if (result.outcome === SetupReminderOutcome.Sent) {
|
|
679
|
+
sentCount++;
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
682
|
+
if (result.outcome === SetupReminderOutcome.Failed) {
|
|
683
|
+
failedCount++;
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
skippedCount++;
|
|
687
|
+
}
|
|
688
|
+
return {
|
|
689
|
+
projectId: projectId,
|
|
690
|
+
requestedCount: requestedCount,
|
|
691
|
+
sentCount: sentCount,
|
|
692
|
+
skippedCount: skippedCount,
|
|
693
|
+
failedCount: failedCount,
|
|
694
|
+
results: results,
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
getThrottleKey(projectId, userId) {
|
|
698
|
+
return `${projectId.toString()}:${userId.toString()}`;
|
|
699
|
+
}
|
|
700
|
+
distinctIds(ids) {
|
|
701
|
+
const seen = new Set();
|
|
702
|
+
const distinct = [];
|
|
703
|
+
for (const id of ids) {
|
|
704
|
+
const key = id.toString();
|
|
705
|
+
if (seen.has(key)) {
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
seen.add(key);
|
|
709
|
+
distinct.push(id);
|
|
710
|
+
}
|
|
711
|
+
return distinct;
|
|
712
|
+
}
|
|
713
|
+
/*
|
|
714
|
+
* The ONLY escaping between a database column and the recipient's inbox -
|
|
715
|
+
* SimpleMessage.hbs renders the message through a triple stache, so nothing
|
|
716
|
+
* downstream escapes anything. Identical to the one in
|
|
717
|
+
* OnCallNotificationAlertingService, and deliberately kept as a private method
|
|
718
|
+
* rather than shared: the two services must be independently auditable, and a
|
|
719
|
+
* shared helper is a shared place for somebody to "improve" the rule for one
|
|
720
|
+
* caller and silently change it for the other.
|
|
721
|
+
*/
|
|
722
|
+
escapeHtml(value) {
|
|
723
|
+
return value
|
|
724
|
+
.replace(/&/g, "&")
|
|
725
|
+
.replace(/</g, "<")
|
|
726
|
+
.replace(/>/g, ">")
|
|
727
|
+
.replace(/"/g, """)
|
|
728
|
+
.replace(/'/g, "'");
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
__decorate([
|
|
732
|
+
CaptureSpan(),
|
|
733
|
+
__metadata("design:type", Function),
|
|
734
|
+
__metadata("design:paramtypes", [Object]),
|
|
735
|
+
__metadata("design:returntype", Promise)
|
|
736
|
+
], OnCallSetupReminderService.prototype, "sendSetupReminders", null);
|
|
737
|
+
export default new OnCallSetupReminderService();
|
|
738
|
+
//# sourceMappingURL=OnCallSetupReminderService.js.map
|