@oneuptime/common 12.0.8 → 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.
Files changed (769) hide show
  1. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +1 -1
  2. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
  3. package/Models/DatabaseModels/AIConversation.ts +32 -0
  4. package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
  5. package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
  6. package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
  7. package/Models/DatabaseModels/Index.ts +12 -4
  8. package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +139 -9
  9. package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
  10. package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +8 -8
  11. package/Models/DatabaseModels/NetworkDevice.ts +141 -0
  12. package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
  13. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
  14. package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
  15. package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
  16. package/Models/DatabaseModels/Project.ts +78 -0
  17. package/Models/DatabaseModels/UserCall.ts +42 -0
  18. package/Models/DatabaseModels/UserEmail.ts +44 -0
  19. package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
  20. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
  21. package/Models/DatabaseModels/UserPush.ts +49 -0
  22. package/Models/DatabaseModels/UserSMS.ts +43 -0
  23. package/Models/DatabaseModels/UserTelegram.ts +59 -0
  24. package/Models/DatabaseModels/UserWebhook.ts +52 -0
  25. package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
  26. package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
  27. package/Server/API/AIChatAPI.ts +315 -1
  28. package/Server/API/DashboardAPI.ts +217 -1
  29. package/Server/API/OnCallReadinessAPI.ts +841 -0
  30. package/Server/API/TeamComplianceAPI.ts +69 -17
  31. package/Server/API/TelemetryAPI.ts +220 -12
  32. package/Server/EnvironmentConfig.ts +52 -0
  33. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  47. package/Server/Infrastructure/Queue.ts +78 -13
  48. package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
  49. package/Server/Services/AIService.ts +7 -0
  50. package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
  51. package/Server/Services/AlertSeverityService.ts +63 -0
  52. package/Server/Services/DashboardService.ts +9 -10
  53. package/Server/Services/DatabaseService.ts +32 -2
  54. package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
  55. package/Server/Services/IncidentSeverityService.ts +76 -0
  56. package/Server/Services/Index.ts +12 -4
  57. package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
  58. package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +4 -4
  59. package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +89 -20
  60. package/Server/Services/LogAggregationService.ts +45 -8
  61. package/Server/Services/MetricAggregationService.ts +121 -0
  62. package/Server/Services/MetricService.ts +7 -7
  63. package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
  64. package/Server/Services/NetworkDeviceLinkService.ts +84 -0
  65. package/Server/Services/NetworkDeviceService.ts +140 -0
  66. package/Server/Services/NetworkSiteService.ts +77 -25
  67. package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
  68. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
  69. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
  70. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
  71. package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
  72. package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
  73. package/Server/Services/OnCallReadinessService.ts +2803 -0
  74. package/Server/Services/OnCallSetupReminderService.ts +955 -0
  75. package/Server/Services/ProfileAggregationService.ts +123 -0
  76. package/Server/Services/StatusPageService.ts +9 -10
  77. package/Server/Services/TeamComplianceService.ts +429 -252
  78. package/Server/Services/UserCallService.ts +26 -1
  79. package/Server/Services/UserEmailService.ts +26 -1
  80. package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
  81. package/Server/Services/UserNotificationRuleService.ts +3812 -333
  82. package/Server/Services/UserOnCallLogService.ts +561 -48
  83. package/Server/Services/UserPushService.ts +29 -0
  84. package/Server/Services/UserService.ts +11 -0
  85. package/Server/Services/UserSmsService.ts +26 -1
  86. package/Server/Services/UserTelegramService.ts +24 -1
  87. package/Server/Services/UserWebhookService.ts +28 -1
  88. package/Server/Services/UserWhatsAppService.ts +24 -1
  89. package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
  90. package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
  91. package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
  92. package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
  93. package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
  94. package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
  95. package/Server/Types/Workflow/Components/API/Get.ts +1 -1
  96. package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
  97. package/Server/Types/Workflow/Components/API/Post.ts +1 -1
  98. package/Server/Types/Workflow/Components/API/Put.ts +1 -1
  99. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
  100. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
  101. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
  102. package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
  103. package/Server/Types/Workflow/Components/Email.ts +25 -7
  104. package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
  105. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
  106. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
  107. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
  108. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
  109. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
  110. package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
  111. package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
  112. package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
  113. package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
  114. package/Server/Utils/AI/Toolbox/Index.ts +48 -0
  115. package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
  116. package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
  117. package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
  118. package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
  119. package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
  120. package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
  121. package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
  122. package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
  123. package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
  124. package/Server/Utils/ClientIp.ts +221 -0
  125. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
  126. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
  127. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
  128. package/Server/Utils/Express.ts +12 -17
  129. package/Server/Utils/LLM/LLMService.ts +85 -8
  130. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
  131. package/Server/Utils/SSRFProtection.ts +98 -23
  132. package/Server/Utils/StartServer.ts +12 -3
  133. package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
  134. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +25 -25
  135. package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
  136. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
  137. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
  138. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
  139. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
  140. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
  141. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
  142. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
  143. package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
  144. package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
  145. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
  146. package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
  147. package/Tests/Models/InventoryItemModel.test.ts +174 -0
  148. package/Tests/Models/InventoryItemNaming.test.ts +302 -0
  149. package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
  150. package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
  151. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
  152. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
  153. package/Tests/Server/API/Helpers.ts +24 -15
  154. package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
  155. package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
  156. package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
  157. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
  158. package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
  159. package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
  160. package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
  161. package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
  162. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
  163. package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
  164. package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
  165. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
  166. package/Tests/Server/Services/{TelemetryEntityManualCreate.test.ts → InventoryItemManualCreate.test.ts} +27 -27
  167. package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
  168. package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
  169. package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
  170. package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
  171. package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
  172. package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
  173. package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
  174. package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
  175. package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
  176. package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
  177. package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
  178. package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
  179. package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
  180. package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
  181. package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
  182. package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
  183. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
  184. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
  185. package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
  186. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
  187. package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
  188. package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
  189. package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
  190. package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
  191. package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
  192. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
  193. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
  194. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
  195. package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
  196. package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
  197. package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
  198. package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
  199. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
  200. package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
  201. package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
  202. package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
  203. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
  204. package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
  205. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
  206. package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
  207. package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
  208. package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
  209. package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
  210. package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
  211. package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
  212. package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
  213. package/Tests/Server/Utils/ClientIp.test.ts +438 -0
  214. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
  215. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
  216. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
  217. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
  218. package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
  219. package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
  220. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
  221. package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
  222. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
  223. package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
  224. package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
  225. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +15 -15
  226. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
  227. package/Tests/Types/IP/IP.test.ts +263 -0
  228. package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
  229. package/Tests/Types/IP/IPv6.test.ts +12 -1
  230. package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
  231. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
  232. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
  233. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
  234. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
  235. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
  236. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
  237. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +6 -6
  238. package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
  239. package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
  240. package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
  241. package/Tests/Types/Workflow/TemplateSyntax.test.ts +112 -0
  242. package/Tests/Types/Workflow/Templates.test.ts +916 -101
  243. package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
  244. package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
  245. package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
  246. package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
  247. package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
  248. package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
  249. package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
  250. package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
  251. package/Tests/UI/Components/Workflow/GraphLint.test.ts +72 -0
  252. package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
  253. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +242 -7
  254. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +15 -7
  255. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +242 -28
  256. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +59 -1
  257. package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
  258. package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
  259. package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
  260. package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
  261. package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
  262. package/Tests/UI/EsbuildConfig.test.ts +607 -0
  263. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
  264. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
  265. package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
  266. package/Tests/UI/Utils/Platform.test.ts +147 -0
  267. package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
  268. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
  269. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +487 -0
  270. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
  271. package/Tests/__mocks__/bullmq.js +55 -0
  272. package/Types/AI/AIChatMessageStatus.ts +8 -1
  273. package/Types/AI/AIChatTypes.ts +12 -0
  274. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
  275. package/Types/Exception/ExceptionCode.ts +2 -0
  276. package/Types/Exception/ServiceUnavailableException.ts +8 -0
  277. package/Types/Exception/TooManyRequestsException.ts +8 -0
  278. package/Types/IP/IP.ts +93 -47
  279. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +49 -3
  280. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
  281. package/Types/OnCallDutyPolicy/Layer.ts +203 -149
  282. package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
  283. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
  284. package/Types/Permission.ts +193 -0
  285. package/Types/Telemetry/EntityRelationshipType.ts +1 -1
  286. package/Types/Telemetry/EntitySource.ts +1 -1
  287. package/Types/Telemetry/EntityType.ts +1 -1
  288. package/Types/Telemetry/EntityTypeGroups.ts +1 -1
  289. package/Types/Workflow/Components/BaseModel.ts +75 -29
  290. package/Types/Workflow/Components/Discord.ts +1 -0
  291. package/Types/Workflow/Components/Email.ts +12 -3
  292. package/Types/Workflow/Components/JavaScript.ts +7 -0
  293. package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
  294. package/Types/Workflow/Components/Slack.ts +1 -0
  295. package/Types/Workflow/Components/Telegram.ts +1 -0
  296. package/Types/Workflow/TemplateSyntax.ts +44 -0
  297. package/Types/Workflow/Templates.ts +2097 -45
  298. package/UI/Components/Calendar/Calendar.css +43 -0
  299. package/UI/Components/Calendar/Calendar.tsx +8 -0
  300. package/UI/Components/Card/Card.tsx +2 -2
  301. package/UI/Components/Checkbox/Checkbox.tsx +16 -0
  302. package/UI/Components/Dictionary/Dictionary.tsx +48 -9
  303. package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
  304. package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
  305. package/UI/Components/Input/Input.tsx +1 -0
  306. package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
  307. package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
  308. package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
  309. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
  310. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
  311. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
  312. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
  313. package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
  314. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
  315. package/UI/Components/LogsViewer/types.ts +23 -0
  316. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
  317. package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
  318. package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
  319. package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
  320. package/UI/Components/Table/Table.tsx +49 -16
  321. package/UI/Components/Table/TableBody.tsx +53 -28
  322. package/UI/Components/Table/TableHeader.tsx +13 -0
  323. package/UI/Components/Table/TableRow.tsx +58 -26
  324. package/UI/Components/Workflow/ArgumentsForm.tsx +155 -9
  325. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
  326. package/UI/Components/Workflow/ComponentSettingsModal.tsx +10 -1
  327. package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
  328. package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
  329. package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
  330. package/UI/Components/Workflow/GraphLint.ts +42 -5
  331. package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
  332. package/UI/Components/Workflow/ModelColumnEditor.tsx +154 -22
  333. package/UI/Components/Workflow/ModelSchema.ts +115 -33
  334. package/UI/Components/Workflow/RunStatusWatcher.ts +1 -1
  335. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  336. package/UI/Components/Workflow/UseRunWatch.ts +212 -0
  337. package/UI/Components/Workflow/VariableModal.tsx +6 -2
  338. package/UI/Components/Workflow/Workflow.tsx +49 -3
  339. package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
  340. package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
  341. package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
  342. package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
  343. package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
  344. package/UI/Utils/Platform.ts +149 -0
  345. package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
  346. package/UI/esbuild-config.js +22 -1
  347. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
  348. package/Utils/Monitor/NetworkTopologyUtil.ts +888 -164
  349. package/Utils/Telemetry/CrossSignalScope.ts +502 -0
  350. package/Utils/Telemetry/EntityKey.ts +5 -5
  351. package/Utils/Telemetry/EntityRelationship.ts +1 -1
  352. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
  353. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
  354. package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
  355. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
  356. package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
  357. package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
  358. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
  359. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
  360. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
  361. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
  362. package/build/dist/Models/DatabaseModels/Index.js +12 -4
  363. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  364. package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +167 -31
  365. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
  366. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
  367. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
  368. package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +27 -27
  369. package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
  370. package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
  371. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  372. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
  373. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
  374. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
  375. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
  376. package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
  377. package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
  378. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
  379. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
  380. package/build/dist/Models/DatabaseModels/Project.js +80 -0
  381. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  382. package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
  383. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  384. package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
  385. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  386. package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
  387. package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
  388. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
  389. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  390. package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
  391. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  392. package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
  393. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  394. package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
  395. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  396. package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
  397. package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
  398. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
  399. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  400. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
  401. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  402. package/build/dist/Server/API/AIChatAPI.js +237 -1
  403. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  404. package/build/dist/Server/API/DashboardAPI.js +165 -13
  405. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  406. package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
  407. package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
  408. package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
  409. package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
  410. package/build/dist/Server/API/TelemetryAPI.js +129 -18
  411. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  412. package/build/dist/Server/EnvironmentConfig.js +45 -0
  413. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  414. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
  415. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  416. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
  417. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
  418. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
  419. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
  420. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
  421. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
  422. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
  423. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
  424. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
  425. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
  426. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
  427. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
  428. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
  429. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
  430. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
  431. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
  432. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
  433. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
  434. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
  435. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
  436. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
  437. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  438. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  439. package/build/dist/Server/Infrastructure/Queue.js +72 -13
  440. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  441. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
  442. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
  443. package/build/dist/Server/Services/AIService.js +1 -0
  444. package/build/dist/Server/Services/AIService.js.map +1 -1
  445. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
  446. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  447. package/build/dist/Server/Services/AlertSeverityService.js +54 -0
  448. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  449. package/build/dist/Server/Services/DashboardService.js +10 -9
  450. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  451. package/build/dist/Server/Services/DatabaseService.js +24 -2
  452. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  453. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
  454. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  455. package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
  456. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  457. package/build/dist/Server/Services/Index.js +12 -4
  458. package/build/dist/Server/Services/Index.js.map +1 -1
  459. package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
  460. package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
  461. package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +6 -6
  462. package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
  463. package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +68 -23
  464. package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
  465. package/build/dist/Server/Services/LogAggregationService.js +27 -8
  466. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  467. package/build/dist/Server/Services/MetricAggregationService.js +80 -0
  468. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  469. package/build/dist/Server/Services/MetricService.js +6 -6
  470. package/build/dist/Server/Services/MetricService.js.map +1 -1
  471. package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
  472. package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
  473. package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
  474. package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
  475. package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
  476. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  477. package/build/dist/Server/Services/NetworkSiteService.js +53 -13
  478. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  479. package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
  480. package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
  481. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
  482. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  483. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
  484. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  485. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
  486. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  487. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
  488. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  489. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
  490. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
  491. package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
  492. package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
  493. package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
  494. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
  495. package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
  496. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
  497. package/build/dist/Server/Services/StatusPageService.js +11 -10
  498. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  499. package/build/dist/Server/Services/TeamComplianceService.js +312 -160
  500. package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
  501. package/build/dist/Server/Services/UserCallService.js +24 -1
  502. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  503. package/build/dist/Server/Services/UserEmailService.js +24 -1
  504. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  505. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
  506. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
  507. package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
  508. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  509. package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
  510. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  511. package/build/dist/Server/Services/UserPushService.js +26 -0
  512. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  513. package/build/dist/Server/Services/UserService.js +10 -0
  514. package/build/dist/Server/Services/UserService.js.map +1 -1
  515. package/build/dist/Server/Services/UserSmsService.js +24 -1
  516. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  517. package/build/dist/Server/Services/UserTelegramService.js +22 -1
  518. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  519. package/build/dist/Server/Services/UserWebhookService.js +25 -1
  520. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  521. package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
  522. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  523. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
  524. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  525. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
  526. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  527. package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
  528. package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
  529. package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
  530. package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
  531. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
  532. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  533. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
  534. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  535. package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
  536. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  537. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
  538. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  539. package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
  540. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  541. package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
  542. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  543. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
  544. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  545. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
  546. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  547. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
  548. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
  549. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
  550. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
  551. package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
  552. package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
  553. package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
  554. package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
  555. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
  556. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  557. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
  558. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  559. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
  560. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  561. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
  562. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  563. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
  564. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  565. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
  566. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  567. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
  568. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
  569. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
  570. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  571. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
  572. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  573. package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
  574. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  575. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
  576. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
  577. package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
  578. package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
  579. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
  580. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
  581. package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
  582. package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
  583. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
  584. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
  585. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
  586. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
  587. package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
  588. package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
  589. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
  590. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
  591. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
  592. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
  593. package/build/dist/Server/Utils/ClientIp.js +137 -0
  594. package/build/dist/Server/Utils/ClientIp.js.map +1 -0
  595. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
  596. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  597. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
  598. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
  599. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
  600. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
  601. package/build/dist/Server/Utils/Express.js +12 -12
  602. package/build/dist/Server/Utils/Express.js.map +1 -1
  603. package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
  604. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  605. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
  606. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  607. package/build/dist/Server/Utils/SSRFProtection.js +82 -21
  608. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  609. package/build/dist/Server/Utils/StartServer.js +12 -4
  610. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  611. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
  612. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  613. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +11 -11
  614. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  615. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
  616. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  617. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
  618. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  619. package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
  620. package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
  621. package/build/dist/Types/AI/AIChatTypes.js +12 -0
  622. package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
  623. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
  624. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
  625. package/build/dist/Types/Exception/ExceptionCode.js +2 -0
  626. package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
  627. package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
  628. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
  629. package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
  630. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
  631. package/build/dist/Types/IP/IP.js +87 -43
  632. package/build/dist/Types/IP/IP.js.map +1 -1
  633. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
  634. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
  635. package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
  636. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  637. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
  638. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
  639. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
  640. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
  641. package/build/dist/Types/Permission.js +174 -0
  642. package/build/dist/Types/Permission.js.map +1 -1
  643. package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
  644. package/build/dist/Types/Telemetry/EntitySource.js +1 -1
  645. package/build/dist/Types/Telemetry/EntityType.js +1 -1
  646. package/build/dist/Types/Telemetry/EntityTypeGroups.js +1 -1
  647. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -1
  648. package/build/dist/Types/Workflow/Components/BaseModel.js +66 -28
  649. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  650. package/build/dist/Types/Workflow/Components/Discord.js +1 -0
  651. package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
  652. package/build/dist/Types/Workflow/Components/Email.js +12 -3
  653. package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
  654. package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
  655. package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
  656. package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
  657. package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
  658. package/build/dist/Types/Workflow/Components/Slack.js +1 -0
  659. package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
  660. package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
  661. package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
  662. package/build/dist/Types/Workflow/TemplateSyntax.js +12 -0
  663. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -1
  664. package/build/dist/Types/Workflow/Templates.js +1931 -38
  665. package/build/dist/Types/Workflow/Templates.js.map +1 -1
  666. package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
  667. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  668. package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
  669. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  670. package/build/dist/UI/Components/Dictionary/Dictionary.js +25 -11
  671. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  672. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  673. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
  674. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  675. package/build/dist/UI/Components/Input/Input.js +1 -0
  676. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  677. package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
  678. package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
  679. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
  680. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
  681. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
  682. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  683. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
  684. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  685. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
  686. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
  687. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
  688. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  689. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
  690. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  691. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
  692. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  693. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
  694. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  695. package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
  696. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
  697. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  698. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
  699. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  700. package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
  701. package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
  702. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
  703. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
  704. package/build/dist/UI/Components/Table/Table.js +27 -15
  705. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  706. package/build/dist/UI/Components/Table/TableBody.js +24 -18
  707. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  708. package/build/dist/UI/Components/Table/TableHeader.js +9 -1
  709. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  710. package/build/dist/UI/Components/Table/TableRow.js +29 -21
  711. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  712. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +130 -12
  713. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  714. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
  715. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  716. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +4 -4
  717. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  718. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
  719. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
  720. package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
  721. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  722. package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
  723. package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
  724. package/build/dist/UI/Components/Workflow/GraphLint.js +33 -4
  725. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -1
  726. package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
  727. package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
  728. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +116 -21
  729. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
  730. package/build/dist/UI/Components/Workflow/ModelSchema.js +72 -34
  731. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -1
  732. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +1 -1
  733. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -1
  734. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  735. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  736. package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
  737. package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
  738. package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
  739. package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
  740. package/build/dist/UI/Components/Workflow/Workflow.js +41 -1
  741. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  742. package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
  743. package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
  744. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
  745. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
  746. package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
  747. package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
  748. package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
  749. package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
  750. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
  751. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  752. package/build/dist/UI/Utils/Platform.js +118 -0
  753. package/build/dist/UI/Utils/Platform.js.map +1 -0
  754. package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
  755. package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
  756. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
  757. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
  758. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +642 -136
  759. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  760. package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
  761. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
  762. package/build/dist/Utils/Telemetry/EntityKey.js +5 -5
  763. package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
  764. package/jest.config.json +1 -0
  765. package/package.json +1 -1
  766. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
  767. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
  768. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
  769. package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
@@ -0,0 +1,880 @@
1
+ import Dashboard from "../../../Models/DatabaseModels/Dashboard";
2
+ import DashboardAPI from "../../../Server/API/DashboardAPI";
3
+ import DashboardService from "../../../Server/Services/DashboardService";
4
+ import ServiceLevelObjectiveService from "../../../Server/Services/ServiceLevelObjectiveService";
5
+ import SloHistoryService from "../../../Server/Services/SloHistoryService";
6
+ import PasswordHash from "../../../Server/Utils/PasswordHash";
7
+ import PublicDashboardSloHistoryPolicy from "../../../Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy";
8
+ import {
9
+ ExpressRequest,
10
+ ExpressResponse,
11
+ NextFunction,
12
+ } from "../../../Server/Utils/Express";
13
+ import Response from "../../../Server/Utils/Response";
14
+ import AggregationInterval from "../../../Types/BaseDatabase/AggregationInterval";
15
+ import AggregationType from "../../../Types/BaseDatabase/AggregationType";
16
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
17
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
18
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
19
+ import DashboardComponentType from "../../../Types/Dashboard/DashboardComponentType";
20
+ import {
21
+ SloWidgetDisplayType,
22
+ SloWidgetMetric,
23
+ } from "../../../Types/Dashboard/DashboardComponents/DashboardSloComponent";
24
+ import DashboardViewConfig from "../../../Types/Dashboard/DashboardViewConfig";
25
+ import HashedString from "../../../Types/HashedString";
26
+ import BadDataException from "../../../Types/Exception/BadDataException";
27
+ import ForbiddenException from "../../../Types/Exception/ForbiddenException";
28
+ import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
29
+ import NotFoundException from "../../../Types/Exception/NotFoundException";
30
+ import { JSONObject } from "../../../Types/JSON";
31
+ import JSONFunctions from "../../../Types/JSONFunctions";
32
+ import ObjectID from "../../../Types/ObjectID";
33
+ import { mockRouter } from "./Helpers";
34
+ import {
35
+ afterEach,
36
+ beforeAll,
37
+ beforeEach,
38
+ describe,
39
+ expect,
40
+ it,
41
+ } from "@jest/globals";
42
+
43
+ jest.mock("../../../Server/Utils/Express", () => {
44
+ return {
45
+ getRouter: () => {
46
+ return mockRouter;
47
+ },
48
+ };
49
+ });
50
+
51
+ jest.mock("../../../Server/Utils/Response", () => {
52
+ return {
53
+ sendEntityArrayResponse: jest.fn().mockImplementation((...args: []) => {
54
+ return args;
55
+ }),
56
+ sendJsonObjectResponse: jest.fn().mockImplementation((...args: []) => {
57
+ return args;
58
+ }),
59
+ sendEmptySuccessResponse: jest.fn(),
60
+ sendEntityResponse: jest.fn().mockImplementation((...args: []) => {
61
+ return args;
62
+ }),
63
+ sendErrorResponse: jest.fn().mockImplementation((...args: []) => {
64
+ return args;
65
+ }),
66
+ };
67
+ });
68
+
69
+ const RESOURCE_LIST_ROUTE: string =
70
+ "/dashboard/resource-list/:dashboardId/:resourceType";
71
+ const SLO_HISTORY_ROUTE: string =
72
+ "/dashboard/slo-history-aggregate/:dashboardId";
73
+
74
+ const RANGE_START: Date = new Date("2026-08-09T00:00:00.000Z");
75
+ const RANGE_END: Date = new Date("2026-08-09T06:00:00.000Z");
76
+
77
+ /*
78
+ * An SLO on a public dashboard is a deliberate publication: the owner drops
79
+ * the widget on a shared board and, by doing so, publishes that one SLO's
80
+ * headline numbers and — for a Chart widget — the series behind them.
81
+ *
82
+ * These tests hold the two halves of that bargain. The widget's data really
83
+ * does reach an anonymous viewer, AND nothing else does: not another SLO in
84
+ * the project, not another series of the same SLO, not the SLO's definition,
85
+ * and not another tenant's project.
86
+ */
87
+ describe("DashboardAPI public SLO", () => {
88
+ let dashboardId: ObjectID;
89
+ let projectId: ObjectID;
90
+ let serviceLevelObjectiveId: ObjectID;
91
+ let dashboard: Dashboard;
92
+ let mockResponse: ExpressResponse;
93
+ let nextFunction: NextFunction;
94
+
95
+ beforeAll(() => {
96
+ mockRouter.routes.length = 0;
97
+ new DashboardAPI();
98
+ });
99
+
100
+ interface BuiltWidget {
101
+ widget: JSONObject;
102
+ componentId: ObjectID;
103
+ }
104
+
105
+ type BuildSloWidgetFunction = (argumentsObject?: JSONObject) => BuiltWidget;
106
+
107
+ const buildSloWidget: BuildSloWidgetFunction = (
108
+ argumentsObject?: JSONObject,
109
+ ): BuiltWidget => {
110
+ const componentId: ObjectID = ObjectID.generate();
111
+
112
+ return {
113
+ componentId,
114
+ widget: {
115
+ _type: "DashboardComponent",
116
+ componentId: componentId.toString(),
117
+ componentType: DashboardComponentType.Slo,
118
+ topInDashboardUnits: 0,
119
+ leftInDashboardUnits: 0,
120
+ widthInDashboardUnits: 3,
121
+ heightInDashboardUnits: 3,
122
+ arguments: {
123
+ serviceLevelObjectiveId: serviceLevelObjectiveId.toString(),
124
+ ...(argumentsObject || {}),
125
+ },
126
+ },
127
+ };
128
+ };
129
+
130
+ type BuildChartWidgetFunction = (argumentsObject?: JSONObject) => BuiltWidget;
131
+
132
+ const buildSloChartWidget: BuildChartWidgetFunction = (
133
+ argumentsObject?: JSONObject,
134
+ ): BuiltWidget => {
135
+ return buildSloWidget({
136
+ displayType: SloWidgetDisplayType.Chart,
137
+ ...(argumentsObject || {}),
138
+ });
139
+ };
140
+
141
+ type SetWidgetsFunction = (widgets: Array<JSONObject>) => void;
142
+
143
+ const setWidgets: SetWidgetsFunction = (widgets: Array<JSONObject>): void => {
144
+ dashboard.dashboardViewConfig = {
145
+ _type: "DashboardViewConfig",
146
+ heightInDashboardUnits: 24,
147
+ components: widgets,
148
+ variables: [],
149
+ } as unknown as DashboardViewConfig;
150
+ };
151
+
152
+ type CallResourceListFunction = (body?: JSONObject) => Promise<void>;
153
+
154
+ const callResourceList: CallResourceListFunction = async (
155
+ body?: JSONObject,
156
+ ): Promise<void> => {
157
+ const request: ExpressRequest = {
158
+ params: {
159
+ dashboardId: dashboardId.toString(),
160
+ resourceType: "slo",
161
+ },
162
+ body: body || {},
163
+ query: {},
164
+ cookies: {},
165
+ headers: {},
166
+ socket: {},
167
+ ips: [],
168
+ } as unknown as ExpressRequest;
169
+
170
+ await mockRouter
171
+ .match("post", RESOURCE_LIST_ROUTE)
172
+ .handlerFunction(request, mockResponse, nextFunction);
173
+ };
174
+
175
+ /*
176
+ * The window a widget really sends, alongside the fields it also sends that
177
+ * the server must throw away.
178
+ */
179
+ type BuildAggregateByFunction = (overrides?: JSONObject) => JSONObject;
180
+
181
+ const buildAggregateBy: BuildAggregateByFunction = (
182
+ overrides?: JSONObject,
183
+ ): JSONObject => {
184
+ return {
185
+ query: {
186
+ projectId: projectId,
187
+ sloId: serviceLevelObjectiveId,
188
+ metricName: "sli.percent",
189
+ bucketStart: new InBetween<Date>(RANGE_START, RANGE_END),
190
+ },
191
+ aggregationType: AggregationType.Avg,
192
+ aggregateColumnName: "value",
193
+ aggregationTimestampColumnName: "bucketStart",
194
+ aggregationInterval: AggregationInterval.FiveMinutes,
195
+ startTimestamp: RANGE_START,
196
+ endTimestamp: RANGE_END,
197
+ sort: { bucketStart: SortOrder.Ascending },
198
+ limit: LIMIT_PER_PROJECT,
199
+ skip: 0,
200
+ ...(overrides || {}),
201
+ } as unknown as JSONObject;
202
+ };
203
+
204
+ type CallSloHistoryFunction = (body?: JSONObject) => Promise<void>;
205
+
206
+ const callSloHistory: CallSloHistoryFunction = async (
207
+ body?: JSONObject,
208
+ ): Promise<void> => {
209
+ const request: ExpressRequest = {
210
+ params: {
211
+ dashboardId: dashboardId.toString(),
212
+ },
213
+ body: body || {},
214
+ query: {},
215
+ cookies: {},
216
+ headers: {},
217
+ socket: {},
218
+ ips: [],
219
+ } as unknown as ExpressRequest;
220
+
221
+ await mockRouter
222
+ .match("post", SLO_HISTORY_ROUTE)
223
+ .handlerFunction(request, mockResponse, nextFunction);
224
+ };
225
+
226
+ type GetFindByArgsFunction = () => JSONObject;
227
+
228
+ const getFindByArgs: GetFindByArgsFunction = (): JSONObject => {
229
+ const calls: Array<Array<unknown>> = (
230
+ ServiceLevelObjectiveService.findBy as jest.Mock
231
+ ).mock.calls as Array<Array<unknown>>;
232
+
233
+ expect(calls.length).toBe(1);
234
+
235
+ return calls[0]![0] as JSONObject;
236
+ };
237
+
238
+ type GetAggregateArgsFunction = () => JSONObject;
239
+
240
+ const getAggregateArgs: GetAggregateArgsFunction = (): JSONObject => {
241
+ const calls: Array<Array<unknown>> = (
242
+ SloHistoryService.aggregateBy as jest.Mock
243
+ ).mock.calls as Array<Array<unknown>>;
244
+
245
+ expect(calls.length).toBe(1);
246
+
247
+ return calls[0]![0] as JSONObject;
248
+ };
249
+
250
+ type GetThrownErrorFunction = () => unknown;
251
+
252
+ const getThrownError: GetThrownErrorFunction = (): unknown => {
253
+ const calls: Array<Array<unknown>> = (nextFunction as jest.Mock).mock
254
+ .calls as Array<Array<unknown>>;
255
+
256
+ expect(calls.length).toBe(1);
257
+
258
+ return calls[0]![0];
259
+ };
260
+
261
+ type ExpectNothingReadFunction = () => void;
262
+
263
+ const expectNothingRead: ExpectNothingReadFunction = (): void => {
264
+ expect(ServiceLevelObjectiveService.findBy).not.toHaveBeenCalled();
265
+ expect(SloHistoryService.aggregateBy).not.toHaveBeenCalled();
266
+ };
267
+
268
+ beforeEach(() => {
269
+ jest.clearAllMocks();
270
+
271
+ dashboardId = ObjectID.generate();
272
+ projectId = ObjectID.generate();
273
+ serviceLevelObjectiveId = ObjectID.generate();
274
+
275
+ dashboard = new Dashboard();
276
+ dashboard.id = dashboardId;
277
+ dashboard.projectId = projectId;
278
+ dashboard.isPublicDashboard = true;
279
+ dashboard.enableMasterPassword = false;
280
+ setWidgets([]);
281
+
282
+ jest.spyOn(DashboardService, "findOneById").mockResolvedValue(dashboard);
283
+ jest
284
+ .spyOn(ServiceLevelObjectiveService, "findBy")
285
+ .mockResolvedValue([] as never);
286
+ jest
287
+ .spyOn(SloHistoryService, "aggregateBy")
288
+ .mockResolvedValue({ data: [] } as never);
289
+
290
+ mockResponse = {
291
+ cookie: jest.fn(),
292
+ send: jest.fn(),
293
+ json: jest.fn(),
294
+ status: jest.fn().mockReturnThis(),
295
+ } as unknown as ExpressResponse;
296
+
297
+ nextFunction = jest.fn();
298
+ });
299
+
300
+ afterEach(() => {
301
+ jest.restoreAllMocks();
302
+ });
303
+
304
+ describe("resource-list: the SLO's current numbers", () => {
305
+ it("serves the SLO the widget names, pinned to the dashboard's project", async () => {
306
+ const slo: BuiltWidget = buildSloWidget();
307
+ setWidgets([slo.widget]);
308
+
309
+ await callResourceList({ componentId: slo.componentId.toString() });
310
+
311
+ expect(nextFunction).not.toHaveBeenCalled();
312
+
313
+ const findByArgs: JSONObject = getFindByArgs();
314
+ const query: JSONObject = findByArgs["query"] as JSONObject;
315
+
316
+ expect(query["projectId"]).toBe(projectId);
317
+ expect((query["_id"] as ObjectID).toString()).toBe(
318
+ serviceLevelObjectiveId.toString(),
319
+ );
320
+ expect(findByArgs["limit"]).toBe(1);
321
+ expect(findByArgs["skip"]).toBe(0);
322
+ expect(findByArgs["props"]).toEqual({ isRoot: true });
323
+ expect(findByArgs["select"]).toEqual({
324
+ _id: true,
325
+ name: true,
326
+ targetPercentage: true,
327
+ currentSliPercentage: true,
328
+ errorBudgetRemainingPercentage: true,
329
+ errorBudgetRemainingSeconds: true,
330
+ currentBurnRate: true,
331
+ sloStatus: true,
332
+ });
333
+ expect(Response.sendEntityArrayResponse).toHaveBeenCalledTimes(1);
334
+ });
335
+
336
+ it("refuses to read an SLO the dashboard does not show", async () => {
337
+ const foreignSloId: ObjectID = ObjectID.generate();
338
+ const slo: BuiltWidget = buildSloWidget();
339
+ setWidgets([slo.widget]);
340
+
341
+ await callResourceList({
342
+ componentId: slo.componentId.toString(),
343
+ query: { _id: foreignSloId.toString() },
344
+ select: { description: true, metricQueryConfig: true, monitors: true },
345
+ sort: { createdAt: SortOrder.Descending },
346
+ limit: LIMIT_PER_PROJECT,
347
+ });
348
+
349
+ const findByArgs: JSONObject = getFindByArgs();
350
+ const query: JSONObject = findByArgs["query"] as JSONObject;
351
+
352
+ expect((query["_id"] as ObjectID).toString()).toBe(
353
+ serviceLevelObjectiveId.toString(),
354
+ );
355
+ expect((query["_id"] as ObjectID).toString()).not.toBe(
356
+ foreignSloId.toString(),
357
+ );
358
+ expect(
359
+ (findByArgs["select"] as JSONObject)["description"],
360
+ ).toBeUndefined();
361
+ expect(
362
+ (findByArgs["select"] as JSONObject)["metricQueryConfig"],
363
+ ).toBeUndefined();
364
+ expect((findByArgs["select"] as JSONObject)["monitors"]).toBeUndefined();
365
+ expect(findByArgs["limit"]).toBe(1);
366
+ });
367
+
368
+ it("refuses the resource entirely when the dashboard has no SLO widget", async () => {
369
+ setWidgets([]);
370
+
371
+ await callResourceList({});
372
+
373
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
374
+ expectNothingRead();
375
+ });
376
+
377
+ it("reads the exact widget when a dashboard shows several SLOs", async () => {
378
+ const otherSloId: ObjectID = ObjectID.generate();
379
+ const first: BuiltWidget = buildSloWidget();
380
+ const second: BuiltWidget = buildSloWidget({
381
+ serviceLevelObjectiveId: otherSloId.toString(),
382
+ });
383
+ setWidgets([first.widget, second.widget]);
384
+
385
+ await callResourceList({ componentId: second.componentId.toString() });
386
+
387
+ const query: JSONObject = getFindByArgs()["query"] as JSONObject;
388
+ expect((query["_id"] as ObjectID).toString()).toBe(otherSloId.toString());
389
+ });
390
+
391
+ it("requires a componentId once more than one SLO widget exists", async () => {
392
+ setWidgets([buildSloWidget().widget, buildSloWidget().widget]);
393
+
394
+ await callResourceList({});
395
+
396
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
397
+ expectNothingRead();
398
+ });
399
+
400
+ it("auto-binds the only SLO widget when no componentId is sent", async () => {
401
+ setWidgets([buildSloWidget().widget]);
402
+
403
+ await callResourceList({});
404
+
405
+ expect(nextFunction).not.toHaveBeenCalled();
406
+ expect(ServiceLevelObjectiveService.findBy).toHaveBeenCalledTimes(1);
407
+ });
408
+
409
+ it("serves a Tile widget as readily as a Chart widget", async () => {
410
+ for (const displayType of Object.values(SloWidgetDisplayType)) {
411
+ jest.clearAllMocks();
412
+ const slo: BuiltWidget = buildSloWidget({ displayType });
413
+ setWidgets([slo.widget]);
414
+
415
+ await callResourceList({ componentId: slo.componentId.toString() });
416
+
417
+ expect(nextFunction).not.toHaveBeenCalled();
418
+ expect(ServiceLevelObjectiveService.findBy).toHaveBeenCalledTimes(1);
419
+ }
420
+ });
421
+
422
+ it("fails closed on a widget whose stored SLO id is missing or malformed", async () => {
423
+ for (const brokenId of [undefined, "", "not-a-uuid"]) {
424
+ jest.clearAllMocks();
425
+ const slo: BuiltWidget = buildSloWidget({
426
+ serviceLevelObjectiveId: brokenId as string,
427
+ });
428
+ setWidgets([slo.widget]);
429
+
430
+ await callResourceList({ componentId: slo.componentId.toString() });
431
+
432
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
433
+ expectNothingRead();
434
+ }
435
+ });
436
+ });
437
+
438
+ describe("slo-history-aggregate: the series behind the numbers", () => {
439
+ it("aggregates only the widget's own SLO and series", async () => {
440
+ const slo: BuiltWidget = buildSloChartWidget({
441
+ sloMetric: SloWidgetMetric.ErrorBudgetRemaining,
442
+ });
443
+ setWidgets([slo.widget]);
444
+
445
+ await callSloHistory({
446
+ componentId: slo.componentId.toString(),
447
+ aggregateBy: buildAggregateBy(),
448
+ });
449
+
450
+ expect(nextFunction).not.toHaveBeenCalled();
451
+
452
+ const aggregateArgs: JSONObject = getAggregateArgs();
453
+ const query: JSONObject = aggregateArgs["query"] as JSONObject;
454
+
455
+ expect(query["projectId"]).toBe(projectId);
456
+ expect((query["sloId"] as ObjectID).toString()).toBe(
457
+ serviceLevelObjectiveId.toString(),
458
+ );
459
+ expect(query["metricName"]).toBe("error.budget.remaining.percent");
460
+
461
+ const bucketStart: InBetween<Date> = query[
462
+ "bucketStart"
463
+ ] as unknown as InBetween<Date>;
464
+ expect(bucketStart).toBeInstanceOf(InBetween);
465
+ expect(new Date(bucketStart.startValue).toISOString()).toBe(
466
+ RANGE_START.toISOString(),
467
+ );
468
+ expect(new Date(bucketStart.endValue).toISOString()).toBe(
469
+ RANGE_END.toISOString(),
470
+ );
471
+
472
+ expect(aggregateArgs["aggregationType"]).toBe(AggregationType.Avg);
473
+ expect(aggregateArgs["aggregateColumnName"]).toBe("value");
474
+ expect(aggregateArgs["aggregationTimestampColumnName"]).toBe(
475
+ "bucketStart",
476
+ );
477
+ expect(aggregateArgs["aggregationInterval"]).toBe(
478
+ AggregationInterval.FiveMinutes,
479
+ );
480
+ expect(aggregateArgs["sort"]).toEqual({
481
+ bucketStart: SortOrder.Ascending,
482
+ });
483
+ expect(aggregateArgs["limit"]).toBe(LIMIT_PER_PROJECT);
484
+ expect(aggregateArgs["skip"]).toBe(0);
485
+ expect(aggregateArgs["props"]).toEqual({ isRoot: true });
486
+ });
487
+
488
+ it("ignores a forged project, SLO, series, column and page", async () => {
489
+ const slo: BuiltWidget = buildSloChartWidget();
490
+ setWidgets([slo.widget]);
491
+
492
+ const foreignProjectId: ObjectID = ObjectID.generate();
493
+ const foreignSloId: ObjectID = ObjectID.generate();
494
+
495
+ await callSloHistory({
496
+ componentId: slo.componentId.toString(),
497
+ aggregateBy: buildAggregateBy({
498
+ query: {
499
+ projectId: foreignProjectId,
500
+ sloId: foreignSloId,
501
+ metricName: "burn.rate",
502
+ bucketStart: new InBetween<Date>(
503
+ new Date("2000-01-01T00:00:00.000Z"),
504
+ new Date("2030-01-01T00:00:00.000Z"),
505
+ ),
506
+ },
507
+ aggregationType: AggregationType.Max,
508
+ aggregateColumnName: "version",
509
+ aggregationTimestampColumnName: "version",
510
+ aggregationInterval: AggregationInterval.Total,
511
+ sort: { version: SortOrder.Descending },
512
+ limit: 1,
513
+ skip: 5000,
514
+ } as unknown as JSONObject),
515
+ });
516
+
517
+ const aggregateArgs: JSONObject = getAggregateArgs();
518
+ const query: JSONObject = aggregateArgs["query"] as JSONObject;
519
+
520
+ expect(query["projectId"]).toBe(projectId);
521
+ expect(query["projectId"]).not.toBe(foreignProjectId);
522
+ expect((query["sloId"] as ObjectID).toString()).toBe(
523
+ serviceLevelObjectiveId.toString(),
524
+ );
525
+ expect(query["metricName"]).toBe("sli.percent");
526
+ expect(aggregateArgs["aggregationType"]).toBe(AggregationType.Avg);
527
+ expect(aggregateArgs["aggregateColumnName"]).toBe("value");
528
+ expect(aggregateArgs["aggregationTimestampColumnName"]).toBe(
529
+ "bucketStart",
530
+ );
531
+ expect(aggregateArgs["aggregationInterval"]).toBe(
532
+ AggregationInterval.FiveMinutes,
533
+ );
534
+ expect(aggregateArgs["limit"]).toBe(LIMIT_PER_PROJECT);
535
+ expect(aggregateArgs["skip"]).toBe(0);
536
+ });
537
+
538
+ it("takes the window from the request", async () => {
539
+ const slo: BuiltWidget = buildSloChartWidget();
540
+ setWidgets([slo.widget]);
541
+
542
+ const start: Date = new Date("2026-07-10T00:00:00.000Z");
543
+ const end: Date = new Date("2026-07-17T00:00:00.000Z");
544
+
545
+ await callSloHistory({
546
+ componentId: slo.componentId.toString(),
547
+ aggregateBy: buildAggregateBy({
548
+ startTimestamp: start,
549
+ endTimestamp: end,
550
+ } as unknown as JSONObject),
551
+ });
552
+
553
+ const aggregateArgs: JSONObject = getAggregateArgs();
554
+ expect(
555
+ new Date(aggregateArgs["startTimestamp"] as string).toISOString(),
556
+ ).toBe(start.toISOString());
557
+ expect(
558
+ new Date(aggregateArgs["endTimestamp"] as string).toISOString(),
559
+ ).toBe(end.toISOString());
560
+ // A week-long window buckets hourly, whatever the caller asked for.
561
+ expect(aggregateArgs["aggregationInterval"]).toBe(
562
+ AggregationInterval.Hour,
563
+ );
564
+ });
565
+
566
+ it("accepts an aggregateBy that has been through the wire serializer", async () => {
567
+ const slo: BuiltWidget = buildSloChartWidget();
568
+ setWidgets([slo.widget]);
569
+
570
+ await callSloHistory({
571
+ componentId: slo.componentId.toString(),
572
+ aggregateBy: JSONFunctions.serialize(
573
+ buildAggregateBy() as JSONObject,
574
+ ) as JSONObject,
575
+ });
576
+
577
+ expect(nextFunction).not.toHaveBeenCalled();
578
+
579
+ const query: JSONObject = getAggregateArgs()["query"] as JSONObject;
580
+ const bucketStart: InBetween<Date> = query[
581
+ "bucketStart"
582
+ ] as unknown as InBetween<Date>;
583
+
584
+ expect(new Date(bucketStart.startValue).toISOString()).toBe(
585
+ RANGE_START.toISOString(),
586
+ );
587
+ expect(new Date(bucketStart.endValue).toISOString()).toBe(
588
+ RANGE_END.toISOString(),
589
+ );
590
+ });
591
+
592
+ it("returns the aggregation result to the viewer", async () => {
593
+ const slo: BuiltWidget = buildSloChartWidget();
594
+ setWidgets([slo.widget]);
595
+
596
+ jest.spyOn(SloHistoryService, "aggregateBy").mockResolvedValue({
597
+ data: [{ timestamp: RANGE_START, value: 99.95 }],
598
+ } as never);
599
+
600
+ await callSloHistory({
601
+ componentId: slo.componentId.toString(),
602
+ aggregateBy: buildAggregateBy(),
603
+ });
604
+
605
+ expect(Response.sendJsonObjectResponse).toHaveBeenCalledTimes(1);
606
+
607
+ const responseBody: JSONObject = (
608
+ Response.sendJsonObjectResponse as jest.Mock
609
+ ).mock.calls[0]![2] as JSONObject;
610
+
611
+ expect((responseBody["data"] as Array<JSONObject>).length).toBe(1);
612
+ });
613
+
614
+ it("refuses a Tile widget, which publishes no series", async () => {
615
+ const slo: BuiltWidget = buildSloWidget({
616
+ displayType: SloWidgetDisplayType.Tile,
617
+ });
618
+ setWidgets([slo.widget]);
619
+
620
+ await callSloHistory({
621
+ componentId: slo.componentId.toString(),
622
+ aggregateBy: buildAggregateBy(),
623
+ });
624
+
625
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
626
+ expectNothingRead();
627
+ });
628
+
629
+ it("refuses a componentId that is not an SLO widget on this dashboard", async () => {
630
+ const slo: BuiltWidget = buildSloChartWidget();
631
+ setWidgets([slo.widget]);
632
+
633
+ for (const componentId of [
634
+ ObjectID.generate().toString(),
635
+ "not-a-uuid",
636
+ 42,
637
+ {},
638
+ ]) {
639
+ jest.clearAllMocks();
640
+
641
+ await callSloHistory({
642
+ componentId: componentId as string,
643
+ aggregateBy: buildAggregateBy(),
644
+ });
645
+
646
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
647
+ expectNothingRead();
648
+ }
649
+ });
650
+
651
+ it("reads the exact chart widget when a dashboard charts several SLOs", async () => {
652
+ const otherSloId: ObjectID = ObjectID.generate();
653
+ const first: BuiltWidget = buildSloChartWidget();
654
+ const second: BuiltWidget = buildSloChartWidget({
655
+ serviceLevelObjectiveId: otherSloId.toString(),
656
+ sloMetric: SloWidgetMetric.BurnRate,
657
+ });
658
+ setWidgets([first.widget, second.widget]);
659
+
660
+ await callSloHistory({
661
+ componentId: second.componentId.toString(),
662
+ aggregateBy: buildAggregateBy(),
663
+ });
664
+
665
+ const query: JSONObject = getAggregateArgs()["query"] as JSONObject;
666
+ expect((query["sloId"] as ObjectID).toString()).toBe(
667
+ otherSloId.toString(),
668
+ );
669
+ expect((query["sloId"] as ObjectID).toString()).not.toBe(
670
+ serviceLevelObjectiveId.toString(),
671
+ );
672
+ expect(query["metricName"]).toBe("burn.rate");
673
+ });
674
+
675
+ it("requires a componentId once more than one SLO widget exists", async () => {
676
+ setWidgets([buildSloChartWidget().widget, buildSloChartWidget().widget]);
677
+
678
+ await callSloHistory({ aggregateBy: buildAggregateBy() });
679
+
680
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
681
+ expectNothingRead();
682
+ });
683
+
684
+ it("refuses when the dashboard has no SLO widget at all", async () => {
685
+ setWidgets([]);
686
+
687
+ await callSloHistory({ aggregateBy: buildAggregateBy() });
688
+
689
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
690
+ expectNothingRead();
691
+ });
692
+
693
+ it("requires an aggregateBy body", async () => {
694
+ const slo: BuiltWidget = buildSloChartWidget();
695
+ setWidgets([slo.widget]);
696
+
697
+ for (const body of [
698
+ {},
699
+ { componentId: slo.componentId.toString() },
700
+ { componentId: slo.componentId.toString(), aggregateBy: null },
701
+ ] as Array<JSONObject>) {
702
+ jest.clearAllMocks();
703
+
704
+ await callSloHistory(body);
705
+
706
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
707
+ expectNothingRead();
708
+ }
709
+ });
710
+
711
+ it("rejects an unusable window before touching ClickHouse", async () => {
712
+ const slo: BuiltWidget = buildSloChartWidget();
713
+ setWidgets([slo.widget]);
714
+
715
+ const brokenWindows: Array<JSONObject> = [
716
+ { startTimestamp: "yesterday" },
717
+ { endTimestamp: null },
718
+ { startTimestamp: RANGE_END, endTimestamp: RANGE_START },
719
+ { startTimestamp: RANGE_START, endTimestamp: RANGE_START },
720
+ ] as unknown as Array<JSONObject>;
721
+
722
+ for (const brokenWindow of brokenWindows) {
723
+ jest.clearAllMocks();
724
+
725
+ await callSloHistory({
726
+ componentId: slo.componentId.toString(),
727
+ aggregateBy: buildAggregateBy(brokenWindow),
728
+ });
729
+
730
+ expect(getThrownError()).toBeInstanceOf(BadDataException);
731
+ expectNothingRead();
732
+ }
733
+ });
734
+
735
+ /*
736
+ * A window reaching past SloHistory's retention is answered, not refused
737
+ * — the public range picker is unbounded and the metric widgets on the
738
+ * same page render whatever it produces. Only the reach back is cut, so
739
+ * ClickHouse is still never asked to grid out decades.
740
+ */
741
+ it("clamps an over-long window instead of erroring the widget", async () => {
742
+ const slo: BuiltWidget = buildSloChartWidget();
743
+ setWidgets([slo.widget]);
744
+
745
+ const endDate: Date = new Date("2026-01-01T00:00:00.000Z");
746
+ const startDate: Date = new Date("2020-01-01T00:00:00.000Z");
747
+
748
+ await callSloHistory({
749
+ componentId: slo.componentId.toString(),
750
+ aggregateBy: buildAggregateBy({
751
+ startTimestamp: startDate,
752
+ endTimestamp: endDate,
753
+ } as unknown as JSONObject),
754
+ });
755
+
756
+ expect(nextFunction).not.toHaveBeenCalled();
757
+
758
+ const aggregateArgs: JSONObject = getAggregateArgs();
759
+ const bucketStart: InBetween<Date> = (
760
+ aggregateArgs["query"] as JSONObject
761
+ )["bucketStart"] as unknown as InBetween<Date>;
762
+
763
+ const retentionInMs: number = 400 * 24 * 60 * 60 * 1000;
764
+ expect(new Date(bucketStart.endValue).toISOString()).toBe(
765
+ endDate.toISOString(),
766
+ );
767
+ expect(new Date(bucketStart.startValue).toISOString()).toBe(
768
+ new Date(endDate.getTime() - retentionInMs).toISOString(),
769
+ );
770
+ expect(new Date(bucketStart.startValue).getTime()).toBeGreaterThan(
771
+ startDate.getTime(),
772
+ );
773
+ });
774
+ });
775
+
776
+ describe("dashboard authorization", () => {
777
+ it("rejects both routes for a dashboard that is not public", async () => {
778
+ const slo: BuiltWidget = buildSloChartWidget();
779
+ setWidgets([slo.widget]);
780
+ dashboard.isPublicDashboard = false;
781
+
782
+ await callResourceList({ componentId: slo.componentId.toString() });
783
+ expect(getThrownError()).toBeInstanceOf(NotAuthenticatedException);
784
+ expectNothingRead();
785
+
786
+ jest.clearAllMocks();
787
+ await callSloHistory({
788
+ componentId: slo.componentId.toString(),
789
+ aggregateBy: buildAggregateBy(),
790
+ });
791
+ expect(getThrownError()).toBeInstanceOf(NotAuthenticatedException);
792
+ expectNothingRead();
793
+ });
794
+
795
+ it("rejects both routes for a dashboard with no project", async () => {
796
+ const slo: BuiltWidget = buildSloChartWidget();
797
+ setWidgets([slo.widget]);
798
+ delete dashboard.projectId;
799
+
800
+ await callResourceList({ componentId: slo.componentId.toString() });
801
+ expect(getThrownError()).toBeInstanceOf(NotFoundException);
802
+ expectNothingRead();
803
+
804
+ jest.clearAllMocks();
805
+ await callSloHistory({
806
+ componentId: slo.componentId.toString(),
807
+ aggregateBy: buildAggregateBy(),
808
+ });
809
+ expect(getThrownError()).toBeInstanceOf(NotFoundException);
810
+ expectNothingRead();
811
+ });
812
+
813
+ /*
814
+ * The two routes must go through DashboardService.hasReadAccess rather
815
+ * than checking `isPublicDashboard` themselves — both already load the
816
+ * dashboard, so open-coding the flag is an easy and silent regression
817
+ * that would drop master-password and IP-allowlist gating entirely.
818
+ */
819
+ it("rejects both routes on a password-protected dashboard with no cookie", async () => {
820
+ const slo: BuiltWidget = buildSloChartWidget();
821
+ setWidgets([slo.widget]);
822
+ dashboard.enableMasterPassword = true;
823
+ dashboard.masterPasswordSalt = PasswordHash.generateSalt();
824
+ dashboard.masterPassword = new HashedString(
825
+ await PasswordHash.hash({
826
+ plainValue: "correct-horse-battery-staple",
827
+ salt: dashboard.masterPasswordSalt,
828
+ }),
829
+ true,
830
+ );
831
+
832
+ await callResourceList({ componentId: slo.componentId.toString() });
833
+ expect(getThrownError()).toBeInstanceOf(NotAuthenticatedException);
834
+ expectNothingRead();
835
+
836
+ jest.clearAllMocks();
837
+ await callSloHistory({
838
+ componentId: slo.componentId.toString(),
839
+ aggregateBy: buildAggregateBy(),
840
+ });
841
+ expect(getThrownError()).toBeInstanceOf(NotAuthenticatedException);
842
+ expectNothingRead();
843
+ });
844
+
845
+ it("rejects both routes when the viewer's IP is not on the allowlist", async () => {
846
+ const slo: BuiltWidget = buildSloChartWidget();
847
+ setWidgets([slo.widget]);
848
+ dashboard.ipWhitelist = "10.0.0.1";
849
+
850
+ await callResourceList({ componentId: slo.componentId.toString() });
851
+ expect(getThrownError()).toBeInstanceOf(ForbiddenException);
852
+ expectNothingRead();
853
+
854
+ jest.clearAllMocks();
855
+ await callSloHistory({
856
+ componentId: slo.componentId.toString(),
857
+ aggregateBy: buildAggregateBy(),
858
+ });
859
+ expect(getThrownError()).toBeInstanceOf(ForbiddenException);
860
+ expectNothingRead();
861
+ });
862
+
863
+ it("checks access before it ever reads the widget", async () => {
864
+ const slo: BuiltWidget = buildSloChartWidget();
865
+ setWidgets([slo.widget]);
866
+ dashboard.isPublicDashboard = false;
867
+
868
+ const buildSpy: jest.SpiedFunction<
869
+ typeof PublicDashboardSloHistoryPolicy.build
870
+ > = jest.spyOn(PublicDashboardSloHistoryPolicy, "build");
871
+
872
+ await callSloHistory({
873
+ componentId: slo.componentId.toString(),
874
+ aggregateBy: buildAggregateBy(),
875
+ });
876
+
877
+ expect(buildSpy).not.toHaveBeenCalled();
878
+ });
879
+ });
880
+ });