@oneuptime/common 14.0.8 → 14.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 (639) hide show
  1. package/Models/DatabaseModels/Index.ts +2 -0
  2. package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
  3. package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
  4. package/Models/DatabaseModels/Project.ts +55 -5
  5. package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
  6. package/Models/DatabaseModels/RunnerJob.ts +75 -0
  7. package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
  8. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
  9. package/Server/API/AIChatAPI.ts +6 -3
  10. package/Server/API/AIInvestigationAPI.ts +17 -10
  11. package/Server/API/AutoRemediationAPI.ts +207 -25
  12. package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
  13. package/Server/API/MicrosoftTeamsAPI.ts +93 -14
  14. package/Server/API/ProxmoxResourceAPI.ts +244 -14
  15. package/Server/Infrastructure/GlobalCache.ts +32 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/TelemetryIngest.ts +41 -18
  21. package/Server/Services/AIService.ts +70 -1
  22. package/Server/Services/AlertService.ts +352 -11
  23. package/Server/Services/AlertSeverityService.ts +65 -15
  24. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  25. package/Server/Services/IncidentService.ts +280 -104
  26. package/Server/Services/IncidentSeverityService.ts +66 -15
  27. package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
  28. package/Server/Services/KubernetesAiAgentService.ts +1634 -0
  29. package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
  30. package/Server/Services/KubernetesClusterService.ts +129 -21
  31. package/Server/Services/ProjectService.ts +32 -0
  32. package/Server/Services/ProxmoxResourceService.ts +322 -5
  33. package/Server/Services/RunnerJobService.ts +241 -104
  34. package/Server/Services/RunnerService.ts +1 -1
  35. package/Server/Services/ScheduledMaintenanceService.ts +737 -1
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
  37. package/Server/Services/TeamComplianceSettingService.ts +1125 -9
  38. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
  39. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
  40. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
  41. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
  42. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
  43. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
  44. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
  45. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
  46. package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
  47. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
  48. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
  49. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
  50. package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
  51. package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
  52. package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
  53. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
  54. package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
  55. package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
  56. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
  57. package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
  58. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
  59. package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
  60. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
  61. package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
  62. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
  63. package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
  64. package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
  65. package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
  66. package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
  67. package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
  68. package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
  69. package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
  70. package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
  71. package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
  72. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
  73. package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
  74. package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
  75. package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
  76. package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
  77. package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
  78. package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
  79. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
  80. package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
  81. package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
  82. package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
  83. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
  84. package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
  85. package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
  86. package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
  87. package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
  88. package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
  89. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
  90. package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
  91. package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
  92. package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
  93. package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
  94. package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
  95. package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
  96. package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
  97. package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
  98. package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
  99. package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
  100. package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
  101. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
  102. package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
  103. package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
  104. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
  105. package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
  106. package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
  107. package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
  108. package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
  109. package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
  110. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
  111. package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
  112. package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
  113. package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
  114. package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
  115. package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
  116. package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
  117. package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
  118. package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
  119. package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
  120. package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
  121. package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
  122. package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
  123. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
  124. package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
  125. package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
  126. package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
  127. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
  128. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
  129. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
  130. package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
  131. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
  132. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
  133. package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
  134. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
  135. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
  136. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
  137. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
  138. package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
  139. package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
  140. package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
  141. package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
  142. package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
  143. package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
  144. package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
  145. package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
  146. package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
  147. package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
  148. package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
  149. package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
  150. package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
  151. package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
  152. package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
  153. package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
  154. package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
  155. package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
  156. package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
  157. package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
  158. package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
  159. package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
  160. package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
  161. package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
  162. package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
  163. package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
  164. package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
  165. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
  166. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
  167. package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
  168. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
  169. package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
  170. package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
  171. package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
  172. package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
  173. package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
  174. package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
  175. package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
  176. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
  177. package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
  178. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
  179. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
  180. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
  181. package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
  182. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
  183. package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
  184. package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
  185. package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
  186. package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
  187. package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
  188. package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
  189. package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
  190. package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
  191. package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
  192. package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
  193. package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
  194. package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
  195. package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
  196. package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
  197. package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
  198. package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
  199. package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
  200. package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
  201. package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
  202. package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
  203. package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
  204. package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
  205. package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
  206. package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
  207. package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
  208. package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
  209. package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
  210. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
  211. package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
  212. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
  213. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
  214. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
  215. package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
  216. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
  217. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
  218. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
  219. package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
  220. package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
  221. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
  222. package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
  223. package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
  224. package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
  225. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
  226. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
  227. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
  228. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
  229. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
  230. package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
  231. package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
  232. package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
  233. package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
  234. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
  235. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
  236. package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
  237. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
  238. package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
  239. package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
  240. package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
  241. package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
  242. package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
  243. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
  244. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
  245. package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
  246. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
  247. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
  248. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
  249. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
  250. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
  251. package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
  252. package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
  253. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
  254. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
  255. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
  256. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
  257. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
  258. package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
  259. package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
  260. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
  261. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
  262. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
  263. package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
  264. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
  265. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
  266. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
  267. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
  268. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
  269. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
  270. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
  271. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
  272. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
  273. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
  274. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
  275. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
  276. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
  277. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
  278. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
  279. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
  280. package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
  281. package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
  282. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
  283. package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
  284. package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
  285. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
  286. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
  287. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
  288. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
  289. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
  290. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
  291. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
  292. package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
  293. package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
  294. package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
  295. package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
  296. package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
  297. package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
  298. package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
  299. package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
  300. package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
  301. package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
  302. package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
  303. package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
  304. package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
  305. package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
  306. package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
  307. package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
  308. package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
  309. package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
  310. package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
  311. package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
  312. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
  313. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
  314. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
  315. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
  316. package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
  317. package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
  318. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
  319. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
  320. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
  321. package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
  322. package/Tests/UI/Components/Input.test.tsx +80 -1
  323. package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
  324. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
  325. package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
  326. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
  327. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
  328. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
  329. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
  330. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
  331. package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
  332. package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
  333. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
  334. package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
  335. package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
  336. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
  337. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
  338. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
  339. package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
  340. package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
  341. package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
  342. package/Tests/UI/Components/Toggle.test.tsx +66 -0
  343. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
  344. package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
  345. package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
  346. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
  347. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
  348. package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
  349. package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
  350. package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
  351. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
  352. package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
  353. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
  354. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
  355. package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
  356. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
  357. package/Types/AI/AIRunType.ts +9 -4
  358. package/Types/AI/InvestigationNotStartedReason.ts +6 -0
  359. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
  360. package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
  361. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
  362. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
  363. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
  364. package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
  365. package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
  366. package/Types/Team/ComplianceNotificationChannel.ts +22 -0
  367. package/Types/Team/ComplianceRule.ts +434 -0
  368. package/Types/Team/ComplianceRuleType.ts +21 -0
  369. package/Types/Team/TeamComplianceStatus.ts +81 -0
  370. package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
  371. package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
  372. package/UI/Components/ActionButton/RowActions.tsx +238 -0
  373. package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
  374. package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
  375. package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
  376. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
  377. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
  378. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
  379. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
  380. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
  381. package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
  382. package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
  383. package/UI/Components/Charts/Line/LineChart.tsx +32 -2
  384. package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
  385. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
  386. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
  387. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
  388. package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
  389. package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
  390. package/UI/Components/Charts/Utils/XAxis.ts +75 -0
  391. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
  392. package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
  393. package/UI/Components/Forms/Fields/FormField.tsx +10 -0
  394. package/UI/Components/Input/Input.tsx +90 -57
  395. package/UI/Components/List/ListRow.tsx +8 -74
  396. package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
  397. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
  398. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
  399. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
  400. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
  401. package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
  402. package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
  403. package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
  404. package/UI/Components/OrderedStatesList/Item.tsx +7 -72
  405. package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
  406. package/UI/Components/Table/TableBody.tsx +8 -2
  407. package/UI/Components/Table/TableRow.tsx +20 -140
  408. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
  409. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
  410. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
  411. package/UI/Components/TelemetryViewer/types.ts +2 -0
  412. package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
  413. package/UI/Components/Toggle/Toggle.tsx +26 -0
  414. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  415. package/UI/Styles/Theme.css +14 -2
  416. package/Utils/AiRemediation/CommandPolicy.ts +1 -1
  417. package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
  418. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
  419. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  420. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
  422. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
  423. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
  424. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  425. package/build/dist/Models/DatabaseModels/Project.js +56 -5
  426. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  427. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
  428. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
  429. package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
  430. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  431. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
  432. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  433. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  434. package/build/dist/Server/API/AIChatAPI.js +6 -1
  435. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  436. package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
  437. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  438. package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
  439. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  440. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
  441. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
  442. package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
  443. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  444. package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
  445. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
  446. package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
  447. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  448. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
  449. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
  450. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
  451. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
  452. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
  453. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
  454. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  455. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  456. package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
  457. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  458. package/build/dist/Server/Services/AIService.js +59 -1
  459. package/build/dist/Server/Services/AIService.js.map +1 -1
  460. package/build/dist/Server/Services/AlertService.js +248 -13
  461. package/build/dist/Server/Services/AlertService.js.map +1 -1
  462. package/build/dist/Server/Services/AlertSeverityService.js +51 -15
  463. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  464. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  465. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  466. package/build/dist/Server/Services/IncidentService.js +199 -72
  467. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  468. package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
  469. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  470. package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
  471. package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
  472. package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
  473. package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
  474. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
  475. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  476. package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
  477. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  478. package/build/dist/Server/Services/ProjectService.js +22 -0
  479. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  480. package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
  481. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  482. package/build/dist/Server/Services/RunnerJobService.js +178 -92
  483. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  484. package/build/dist/Server/Services/RunnerService.js +1 -1
  485. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  486. package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
  487. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  488. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
  489. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  490. package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
  491. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  492. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
  493. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
  494. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
  495. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  496. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
  497. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  498. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
  499. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  500. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
  501. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  502. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
  503. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  504. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
  505. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  506. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
  507. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  508. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
  509. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
  510. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  511. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
  512. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  513. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
  514. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  515. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
  516. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
  517. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
  518. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
  519. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
  520. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  521. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
  522. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  523. package/build/dist/Types/AI/AIRunType.js +9 -4
  524. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  525. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
  526. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  527. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
  528. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
  529. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
  530. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  531. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
  532. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
  533. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
  534. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
  535. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
  536. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  537. package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
  538. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
  539. package/build/dist/Types/Team/ComplianceRule.js +304 -0
  540. package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
  541. package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
  542. package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
  543. package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
  544. package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
  545. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
  546. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  547. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
  548. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
  549. package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
  550. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
  551. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
  552. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
  553. package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
  554. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  555. package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
  556. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
  558. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
  560. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
  562. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
  564. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  565. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
  566. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
  567. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
  568. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
  569. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
  570. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
  571. package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
  572. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  573. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
  574. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
  575. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
  576. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
  577. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
  578. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
  579. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
  580. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
  581. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
  582. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
  583. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
  584. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  585. package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
  586. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  587. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
  588. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
  589. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
  590. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  591. package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
  592. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  593. package/build/dist/UI/Components/Input/Input.js +69 -54
  594. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  595. package/build/dist/UI/Components/List/ListRow.js +4 -39
  596. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  597. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
  598. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  599. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
  600. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  601. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
  602. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  603. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
  604. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  605. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  606. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  607. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
  608. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  609. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
  610. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  611. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
  612. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  613. package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
  614. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  615. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
  616. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  617. package/build/dist/UI/Components/Table/TableBody.js +6 -2
  618. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  619. package/build/dist/UI/Components/Table/TableRow.js +12 -75
  620. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  621. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
  622. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  623. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
  624. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  625. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
  626. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  627. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
  628. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
  629. package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
  630. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  631. package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
  632. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  633. package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
  634. package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
  635. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
  636. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
  637. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
  638. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
  639. package/package.json +1 -1
@@ -65,6 +65,7 @@ import UserService from "../../../Services/UserService";
65
65
  import QueryHelper from "../../../Types/Database/QueryHelper";
66
66
  import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
67
67
  import LIMIT_MAX from "../../../../Types/Database/LimitMax";
68
+ import { truncateToLength } from "../../Database/TruncateColumnValue";
68
69
 
69
70
  // Bot Framework SDK imports
70
71
  import {
@@ -164,6 +165,64 @@ export enum MicrosoftTeamsAppInstallState {
164
165
  export const MICROSOFT_TEAMS_INSTALL_READ_PERMISSION: string =
165
166
  "TeamsAppInstallation.ReadForTeam.All";
166
167
 
168
+ /*
169
+ * The resource-specific (per chat) permission that lets OneUptime read a group
170
+ * chat's name (its Graph "topic") with the app-only token. Bot Framework
171
+ * activities from group chats do not reliably carry the name, so without this
172
+ * a group chat can only be named after its members. It is granted per chat
173
+ * when the app is installed or updated there with a manifest that requests it.
174
+ * (The tenant-wide Chat.ReadBasic.WhereInstalled application permission works
175
+ * with the same call, for admins who would rather grant it once.)
176
+ */
177
+ export const MICROSOFT_TEAMS_CHAT_TOPIC_READ_PERMISSION: string =
178
+ "ChatSettings.Read.Chat";
179
+
180
+ export enum MicrosoftTeamsChatTopicLookupStatus {
181
+ Found = "Found", // the chat has a name in Teams.
182
+ NoTopic = "NoTopic", // the chat exists but nobody has named it.
183
+ PermissionDenied = "PermissionDenied",
184
+ Unknown = "Unknown",
185
+ }
186
+
187
+ export interface MicrosoftTeamsChatTopicLookup {
188
+ status: MicrosoftTeamsChatTopicLookupStatus;
189
+ topic?: string | undefined; // set only when status is Found.
190
+ }
191
+
192
+ export interface MicrosoftTeamsChatNameRefreshResult {
193
+ // The project's chats as stored once the refresh has been written.
194
+ chats: Record<string, MicrosoftTeamsChat>;
195
+ // Group chats whose name Microsoft refused to share (permission missing).
196
+ permissionDeniedChatIds: Array<string>;
197
+ // Group chats whose name could not be read for any other reason.
198
+ failedChatIds: Array<string>;
199
+ }
200
+
201
+ // A chat's name and the Teams name it was built from, as Refresh Chats writes them.
202
+ export interface MicrosoftTeamsChatNameUpdate {
203
+ name: string;
204
+ topic?: string | undefined; // absent: the chat has no name in Teams.
205
+ }
206
+
207
+ // How many Graph chat lookups Refresh Chats runs at once.
208
+ const MICROSOFT_TEAMS_CHAT_TOPIC_LOOKUP_CONCURRENCY: number = 5;
209
+
210
+ /*
211
+ * Per-lookup ceiling. Concurrent refreshes of a project share one run, so a
212
+ * lookup that never answers would otherwise hold every later Refresh Chats
213
+ * for that project.
214
+ */
215
+ const MICROSOFT_TEAMS_CHAT_TOPIC_LOOKUP_TIMEOUT_IN_MS: number = 15000;
216
+
217
+ /*
218
+ * Chat names are kept well under the 100-character ShortText columns that
219
+ * store them in notification logs — Teams chat names can be much longer.
220
+ */
221
+ const MICROSOFT_TEAMS_CHAT_NAME_MAX_LENGTH: number = 80;
222
+
223
+ // How many member names a group chat named after its members shows.
224
+ const MICROSOFT_TEAMS_CHAT_NAME_MEMBERS_SHOWN: number = 3;
225
+
167
226
  /*
168
227
  * Microsoft's wording when the Bot Framework refuses a proactive post because
169
228
  * the app is not a member of the target conversation. Matched case-insensitively
@@ -4507,28 +4566,30 @@ All monitoring checks are passing normally.`;
4507
4566
  chatType: MicrosoftTeamsChatType;
4508
4567
  topic?: string | undefined;
4509
4568
  memberNames: Array<string>;
4510
- }): string {
4511
4569
  /*
4512
- * Keep well under the 100-char ShortText columns that store the chat
4513
- * name in notification logs — Teams chat topics can be much longer.
4570
+ * How many members have a name, when memberNames holds only the first
4571
+ * few of them (as stored chats do). Defaults to memberNames' own count.
4514
4572
  */
4515
- const maxNameLength: number = 80;
4516
-
4573
+ memberCount?: number | undefined;
4574
+ }): string {
4517
4575
  const truncate: (name: string) => string = (name: string): string => {
4518
- return name.length > maxNameLength
4519
- ? `${name.substring(0, maxNameLength - 1)}…`
4520
- : name;
4576
+ if (name.length <= MICROSOFT_TEAMS_CHAT_NAME_MAX_LENGTH) {
4577
+ return name;
4578
+ }
4579
+
4580
+ /*
4581
+ * Cut by UTF-16 code units, but never between the two halves of an
4582
+ * emoji: a lone surrogate makes Postgres refuse the whole jsonb write
4583
+ * that carries the name.
4584
+ */
4585
+ return `${truncateToLength(name, MICROSOFT_TEAMS_CHAT_NAME_MAX_LENGTH - 1)}…`;
4521
4586
  };
4522
4587
 
4523
4588
  if (data.topic && data.topic.trim()) {
4524
4589
  return truncate(data.topic.trim());
4525
4590
  }
4526
4591
 
4527
- const memberNames: Array<string> = data.memberNames.filter(
4528
- (name: string) => {
4529
- return Boolean(name && name.trim());
4530
- },
4531
- );
4592
+ const memberNames: Array<string> = this.getNonBlankNames(data.memberNames);
4532
4593
 
4533
4594
  if (data.chatType === "personal") {
4534
4595
  return memberNames[0] ? truncate(`${memberNames[0]}`) : "Personal chat";
@@ -4538,9 +4599,15 @@ All monitoring checks are passing normally.`;
4538
4599
  return "Group chat";
4539
4600
  }
4540
4601
 
4541
- const maxNamesToShow: number = 3;
4542
- const shownNames: Array<string> = memberNames.slice(0, maxNamesToShow);
4543
- const remainingCount: number = memberNames.length - shownNames.length;
4602
+ const shownNames: Array<string> = memberNames.slice(
4603
+ 0,
4604
+ MICROSOFT_TEAMS_CHAT_NAME_MEMBERS_SHOWN,
4605
+ );
4606
+ const memberCount: number = Math.max(
4607
+ data.memberCount || 0,
4608
+ memberNames.length,
4609
+ );
4610
+ const remainingCount: number = memberCount - shownNames.length;
4544
4611
 
4545
4612
  if (remainingCount > 0) {
4546
4613
  return truncate(`${shownNames.join(", ")} + ${remainingCount} more`);
@@ -4549,6 +4616,119 @@ All monitoring checks are passing normally.`;
4549
4616
  return truncate(shownNames.join(", "));
4550
4617
  }
4551
4618
 
4619
+ private static getNonBlankNames(names: Array<string>): Array<string> {
4620
+ return names.filter((name: string) => {
4621
+ return Boolean(name && name.trim());
4622
+ });
4623
+ }
4624
+
4625
+ /*
4626
+ * Builds the record to store for a chat that was just heard from, on top of
4627
+ * what is already stored. Whatever could not be read this time — the name
4628
+ * (Graph refused, failed, or was not asked) or the roster (the Bot Framework
4629
+ * call failed) — is taken from the stored record instead of being dropped:
4630
+ * a failed lookup must never turn a chat's real name back into member
4631
+ * names, or member names into a bare "Group chat".
4632
+ */
4633
+ public static buildCapturedChat(data: {
4634
+ chatId: string;
4635
+ chatType: MicrosoftTeamsChatType;
4636
+ serviceUrl?: string | undefined;
4637
+ // conversation.name from the activity, when Teams sent one.
4638
+ activityTopic?: string | undefined;
4639
+ // The Graph answer; undefined when Graph was not asked.
4640
+ topicLookup?: MicrosoftTeamsChatTopicLookup | undefined;
4641
+ // The chat's human members; null when the roster could not be read.
4642
+ roster: {
4643
+ memberNames: Array<string>;
4644
+ memberAadObjectIds: Array<string>;
4645
+ } | null;
4646
+ storedChat?: MicrosoftTeamsChat | undefined;
4647
+ now: string;
4648
+ }): MicrosoftTeamsChat {
4649
+ const storedChat: MicrosoftTeamsChat | undefined = data.storedChat;
4650
+ const activityTopic: string = (data.activityTopic || "").trim();
4651
+ const lookupStatus: MicrosoftTeamsChatTopicLookupStatus | undefined =
4652
+ data.topicLookup?.status;
4653
+ const topicCleared: boolean =
4654
+ !activityTopic &&
4655
+ lookupStatus === MicrosoftTeamsChatTopicLookupStatus.NoTopic;
4656
+
4657
+ let topic: string | undefined = undefined;
4658
+
4659
+ if (activityTopic) {
4660
+ topic = activityTopic;
4661
+ } else if (lookupStatus === MicrosoftTeamsChatTopicLookupStatus.Found) {
4662
+ topic = data.topicLookup?.topic;
4663
+ } else if (!topicCleared) {
4664
+ topic = storedChat?.topic; // not read this time: keep the last known name.
4665
+ }
4666
+
4667
+ let memberNames: Array<string> | undefined = storedChat?.memberNames?.slice(
4668
+ 0,
4669
+ MICROSOFT_TEAMS_CHAT_NAME_MEMBERS_SHOWN,
4670
+ );
4671
+ let memberCount: number | undefined = storedChat?.memberCount;
4672
+ let memberAadObjectIds: Array<string> =
4673
+ storedChat?.memberAadObjectIds || [];
4674
+
4675
+ if (data.roster) {
4676
+ const names: Array<string> = this.getNonBlankNames(
4677
+ data.roster.memberNames,
4678
+ );
4679
+ memberNames = names.slice(0, MICROSOFT_TEAMS_CHAT_NAME_MEMBERS_SHOWN);
4680
+ memberCount = names.length;
4681
+ memberAadObjectIds = data.roster.memberAadObjectIds;
4682
+ }
4683
+
4684
+ let name: string;
4685
+
4686
+ if (topic || (memberNames && memberNames.length > 0)) {
4687
+ name = this.getChatDisplayName({
4688
+ chatType: data.chatType,
4689
+ topic: topic,
4690
+ memberNames: memberNames || [],
4691
+ memberCount: memberCount,
4692
+ });
4693
+ } else if (storedChat?.name && !(topicCleared && storedChat.topic)) {
4694
+ /*
4695
+ * Nothing to build a name from this time. The stored name is still the
4696
+ * best there is — unless it was the Teams name, and Teams just said the
4697
+ * chat no longer has one.
4698
+ */
4699
+ name = storedChat.name;
4700
+ } else {
4701
+ name = this.getChatDisplayName({
4702
+ chatType: data.chatType,
4703
+ memberNames: [],
4704
+ });
4705
+ }
4706
+
4707
+ const chat: MicrosoftTeamsChat = {
4708
+ id: data.chatId,
4709
+ name: name,
4710
+ chatType: data.chatType,
4711
+ serviceUrl: data.serviceUrl,
4712
+ // When the chat was first connected; hearing from it again is not that.
4713
+ addedAt: storedChat?.addedAt || data.now,
4714
+ memberAadObjectIds: memberAadObjectIds,
4715
+ };
4716
+
4717
+ if (topic) {
4718
+ chat.topic = topic;
4719
+ }
4720
+
4721
+ if (memberNames !== undefined) {
4722
+ chat.memberNames = memberNames;
4723
+ }
4724
+
4725
+ if (memberCount !== undefined) {
4726
+ chat.memberCount = memberCount;
4727
+ }
4728
+
4729
+ return chat;
4730
+ }
4731
+
4552
4732
  /*
4553
4733
  * Returns true when every connected project of this tenant already has
4554
4734
  * this chat stored with the same service URL — i.e. there is nothing to
@@ -4604,6 +4784,21 @@ All monitoring checks are passing normally.`;
4604
4784
  ) {
4605
4785
  return false;
4606
4786
  }
4787
+
4788
+ /*
4789
+ * Group chats captured before member counts were stored were also
4790
+ * captured before OneUptime asked Graph for their name. Re-capture
4791
+ * them once: that stores the roster (so the name can fall back to the
4792
+ * members if the chat's name is ever removed), and reads the name if
4793
+ * the chat already lets OneUptime read it. Chats the app was added to
4794
+ * with an older manifest only allow that once the app is updated in the
4795
+ * chat, which sends no activity — Refresh Chats picks the name up then.
4796
+ * A roster that could not be read leaves the count unset, so the next
4797
+ * message tries again.
4798
+ */
4799
+ if (chat.chatType === "groupChat" && chat.memberCount === undefined) {
4800
+ return false;
4801
+ }
4607
4802
  }
4608
4803
 
4609
4804
  return true;
@@ -4667,12 +4862,16 @@ All monitoring checks are passing normally.`;
4667
4862
  }
4668
4863
 
4669
4864
  // Resolve a human friendly name for the chat.
4670
- const topic: string | undefined = conversation["name"] as
4671
- | string
4672
- | undefined;
4865
+ const activityTopic: string =
4866
+ typeof conversation["name"] === "string"
4867
+ ? (conversation["name"] as string).trim()
4868
+ : "";
4673
4869
 
4674
- let memberNames: Array<string> = [];
4675
- let memberAadObjectIds: Array<string> = [];
4870
+ // null when the roster could not be read.
4871
+ let roster: {
4872
+ memberNames: Array<string>;
4873
+ memberAadObjectIds: Array<string>;
4874
+ } | null = null;
4676
4875
 
4677
4876
  try {
4678
4877
  const botId: string | undefined =
@@ -4700,39 +4899,60 @@ All monitoring checks are passing normally.`;
4700
4899
  },
4701
4900
  );
4702
4901
 
4703
- memberNames = humanMembers.map((member: TeamsChannelAccount) => {
4704
- return member.name || "";
4705
- });
4706
-
4707
- /*
4708
- * The Entra object id is what maps a chat member back to the
4709
- * OneUptime user who connected that Teams account, so personal chats
4710
- * can serve as direct-message delivery targets.
4711
- */
4712
- memberAadObjectIds = humanMembers
4713
- .map((member: TeamsChannelAccount) => {
4714
- return member.aadObjectId || "";
4715
- })
4716
- .filter((aadObjectId: string) => {
4717
- return Boolean(aadObjectId);
4718
- });
4902
+ roster = {
4903
+ memberNames: humanMembers.map((member: TeamsChannelAccount) => {
4904
+ return member.name || "";
4905
+ }),
4906
+ /*
4907
+ * The Entra object id is what maps a chat member back to the
4908
+ * OneUptime user who connected that Teams account, so personal
4909
+ * chats can serve as direct-message delivery targets.
4910
+ */
4911
+ memberAadObjectIds: humanMembers
4912
+ .map((member: TeamsChannelAccount) => {
4913
+ return member.aadObjectId || "";
4914
+ })
4915
+ .filter((aadObjectId: string) => {
4916
+ return Boolean(aadObjectId);
4917
+ }),
4918
+ };
4719
4919
  } catch (err) {
4720
4920
  logger.debug("Could not fetch chat members for chat name resolution");
4721
4921
  logger.debug(err);
4722
4922
  }
4723
4923
 
4724
- const chat: MicrosoftTeamsChat = {
4725
- id: chatId,
4726
- name: this.getChatDisplayName({
4727
- chatType: chatType,
4728
- topic: topic,
4729
- memberNames: memberNames,
4730
- }),
4924
+ const tenantChat: {
4925
+ projectId: ObjectID | null;
4926
+ storedChat: MicrosoftTeamsChat | undefined;
4927
+ } = await this.getTenantChatContext({
4928
+ tenantId: tenantId,
4929
+ chatId: chatId,
4930
+ });
4931
+
4932
+ /*
4933
+ * Teams does not reliably put a group chat's name on its activities, so
4934
+ * a named group chat would otherwise be listed by its members. Graph has
4935
+ * the name; ask it. Personal chats have no name to find.
4936
+ */
4937
+ let topicLookup: MicrosoftTeamsChatTopicLookup | undefined = undefined;
4938
+
4939
+ if (chatType === "groupChat" && !activityTopic && tenantChat.projectId) {
4940
+ topicLookup = await this.getGroupChatTopicFromGraph({
4941
+ projectId: tenantChat.projectId,
4942
+ chatId: chatId,
4943
+ });
4944
+ }
4945
+
4946
+ const chat: MicrosoftTeamsChat = this.buildCapturedChat({
4947
+ chatId: chatId,
4731
4948
  chatType: chatType,
4732
4949
  serviceUrl: activityServiceUrl,
4733
- addedAt: OneUptimeDate.getCurrentDate().toISOString(),
4734
- memberAadObjectIds: memberAadObjectIds,
4735
- };
4950
+ activityTopic: activityTopic,
4951
+ topicLookup: topicLookup,
4952
+ roster: roster,
4953
+ storedChat: tenantChat.storedChat,
4954
+ now: OneUptimeDate.getCurrentDate().toISOString(),
4955
+ });
4736
4956
 
4737
4957
  await this.saveChatToProjectAuthTokens({
4738
4958
  tenantId: tenantId,
@@ -4887,6 +5107,423 @@ All monitoring checks are passing normally.`;
4887
5107
  }
4888
5108
  }
4889
5109
 
5110
+ /*
5111
+ * What a bot activity needs to know about its tenant before storing a chat:
5112
+ * any project connected to the tenant (bot activities identify the tenant,
5113
+ * not the project, and every project of a tenant yields the same Graph app
5114
+ * token), and the chat as it is stored now, so a re-capture builds on it.
5115
+ *
5116
+ * A failed read throws: capturing without knowing what is stored would
5117
+ * overwrite a chat's real name with whatever this activity could supply.
5118
+ */
5119
+ private static async getTenantChatContext(data: {
5120
+ tenantId: string;
5121
+ chatId: string;
5122
+ }): Promise<{
5123
+ projectId: ObjectID | null;
5124
+ storedChat: MicrosoftTeamsChat | undefined;
5125
+ }> {
5126
+ let projectId: ObjectID | null = null;
5127
+ let storedChat: MicrosoftTeamsChat | undefined = undefined;
5128
+
5129
+ const projectAuths: Array<WorkspaceProjectAuthToken> =
5130
+ await WorkspaceProjectAuthTokenService.findBy({
5131
+ query: {
5132
+ workspaceType: WorkspaceType.MicrosoftTeams,
5133
+ workspaceProjectId: data.tenantId,
5134
+ },
5135
+ select: {
5136
+ _id: true,
5137
+ projectId: true,
5138
+ miscData: true,
5139
+ },
5140
+ limit: LIMIT_MAX,
5141
+ skip: 0,
5142
+ props: {
5143
+ isRoot: true,
5144
+ },
5145
+ });
5146
+
5147
+ for (const projectAuth of projectAuths) {
5148
+ if (!projectId && projectAuth.projectId) {
5149
+ projectId = projectAuth.projectId;
5150
+ }
5151
+
5152
+ if (!storedChat) {
5153
+ storedChat = (projectAuth.miscData as MicrosoftTeamsMiscData)
5154
+ ?.availableChats?.[data.chatId];
5155
+ }
5156
+ }
5157
+
5158
+ return { projectId: projectId, storedChat: storedChat };
5159
+ }
5160
+
5161
+ /*
5162
+ * Reads a group chat's name from Graph (GET /chats/{id}). Only group chats
5163
+ * are looked up: their Bot Framework conversation id is also their Graph
5164
+ * chat id, and they are the only chats that can be named.
5165
+ *
5166
+ * Never throws. A refusal comes back as PermissionDenied — the app-only
5167
+ * token needs ChatSettings.Read.Chat (granted per chat, and chats the app
5168
+ * was added to before the manifest requested it do not have it) or the
5169
+ * tenant-wide Chat.ReadBasic.WhereInstalled. Pass accessToken when looking
5170
+ * up many chats, so the token is fetched once rather than once per chat.
5171
+ */
5172
+ @CaptureSpan()
5173
+ public static async getGroupChatTopicFromGraph(data: {
5174
+ projectId: ObjectID;
5175
+ chatId: string;
5176
+ accessToken?: string | undefined;
5177
+ }): Promise<MicrosoftTeamsChatTopicLookup> {
5178
+ if (!data.chatId) {
5179
+ return { status: MicrosoftTeamsChatTopicLookupStatus.Unknown };
5180
+ }
5181
+
5182
+ try {
5183
+ const accessToken: string =
5184
+ data.accessToken ||
5185
+ (await this.getValidAccessToken({
5186
+ authToken: "",
5187
+ projectId: data.projectId,
5188
+ }));
5189
+
5190
+ const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
5191
+ await API.get<JSONObject>({
5192
+ url: URL.fromString(
5193
+ `https://graph.microsoft.com/v1.0/chats/${encodeURIComponent(
5194
+ data.chatId,
5195
+ )}`,
5196
+ ),
5197
+ headers: {
5198
+ Authorization: `Bearer ${accessToken}`,
5199
+ "Content-Type": "application/json",
5200
+ },
5201
+ options: {
5202
+ timeout: MICROSOFT_TEAMS_CHAT_TOPIC_LOOKUP_TIMEOUT_IN_MS,
5203
+ },
5204
+ });
5205
+
5206
+ if (response instanceof HTTPErrorResponse) {
5207
+ if (this.isGraphPermissionDeniedResponse(response)) {
5208
+ logger.debug(
5209
+ `Cannot read the name of Microsoft Teams chat ${data.chatId}: Microsoft Graph denied the request. The OneUptime app in that chat needs the ${MICROSOFT_TEAMS_CHAT_TOPIC_READ_PERMISSION} permission — update the app in the chat so Teams grants it.`,
5210
+ );
5211
+ return {
5212
+ status: MicrosoftTeamsChatTopicLookupStatus.PermissionDenied,
5213
+ };
5214
+ }
5215
+
5216
+ /*
5217
+ * A 404 for a chat the bot is in would mean the Bot Framework
5218
+ * conversation id is not the Graph chat id — worth seeing in
5219
+ * production logs, unlike a passing throttle or outage.
5220
+ */
5221
+ if (response.statusCode === 404) {
5222
+ logger.warn(
5223
+ `Microsoft Graph has no chat with the id of Microsoft Teams chat ${data.chatId}, so its name cannot be read.`,
5224
+ );
5225
+ } else {
5226
+ logger.debug(`Could not read Microsoft Teams chat ${data.chatId}:`);
5227
+ logger.debug(response);
5228
+ }
5229
+
5230
+ return { status: MicrosoftTeamsChatTopicLookupStatus.Unknown };
5231
+ }
5232
+
5233
+ const topic: unknown = response.data?.["topic"];
5234
+
5235
+ if (typeof topic === "string" && topic.trim()) {
5236
+ return {
5237
+ status: MicrosoftTeamsChatTopicLookupStatus.Found,
5238
+ topic: topic.trim(),
5239
+ };
5240
+ }
5241
+
5242
+ return { status: MicrosoftTeamsChatTopicLookupStatus.NoTopic };
5243
+ } catch (err) {
5244
+ logger.debug(`Error reading Microsoft Teams chat ${data.chatId}:`);
5245
+ logger.debug(err);
5246
+ return { status: MicrosoftTeamsChatTopicLookupStatus.Unknown };
5247
+ }
5248
+ }
5249
+
5250
+ // Refreshes in progress, by project: a second click joins the first.
5251
+ private static chatNameRefreshesInFlight: Map<
5252
+ string,
5253
+ Promise<MicrosoftTeamsChatNameRefreshResult>
5254
+ > = new Map();
5255
+
5256
+ /*
5257
+ * What "Refresh Chats" does. Microsoft does not let an app list chats, but
5258
+ * it does let it read one it is in — so every stored group chat is re-read,
5259
+ * which fixes chats captured under their member names and picks up renames.
5260
+ *
5261
+ * A chat whose name was removed in Teams goes back to its member names when
5262
+ * they were stored with it; otherwise it keeps its current name, unless
5263
+ * that was the removed Teams name. A chat whose name could not be read is
5264
+ * left as it is and reported, so the page can say why.
5265
+ *
5266
+ * Concurrent refreshes of one project (within this App process) share a
5267
+ * single run, so a held-down button costs one pass over the chats, not one
5268
+ * per click.
5269
+ */
5270
+ public static async refreshChatNamesForProject(data: {
5271
+ projectId: ObjectID;
5272
+ }): Promise<MicrosoftTeamsChatNameRefreshResult> {
5273
+ const key: string = data.projectId.toString();
5274
+
5275
+ const inFlight: Promise<MicrosoftTeamsChatNameRefreshResult> | undefined =
5276
+ this.chatNameRefreshesInFlight.get(key);
5277
+
5278
+ if (inFlight) {
5279
+ return inFlight;
5280
+ }
5281
+
5282
+ const refresh: Promise<MicrosoftTeamsChatNameRefreshResult> =
5283
+ this.runChatNameRefresh(data).finally(() => {
5284
+ this.chatNameRefreshesInFlight.delete(key);
5285
+ });
5286
+
5287
+ this.chatNameRefreshesInFlight.set(key, refresh);
5288
+
5289
+ return refresh;
5290
+ }
5291
+
5292
+ @CaptureSpan()
5293
+ private static async runChatNameRefresh(data: {
5294
+ projectId: ObjectID;
5295
+ }): Promise<MicrosoftTeamsChatNameRefreshResult> {
5296
+ const projectAuth: WorkspaceProjectAuthToken | null =
5297
+ await WorkspaceProjectAuthTokenService.getProjectAuth({
5298
+ projectId: data.projectId,
5299
+ workspaceType: WorkspaceType.MicrosoftTeams,
5300
+ });
5301
+
5302
+ const storedChats: Record<string, MicrosoftTeamsChat> =
5303
+ (projectAuth?.miscData as MicrosoftTeamsMiscData | undefined)
5304
+ ?.availableChats || {};
5305
+
5306
+ const result: MicrosoftTeamsChatNameRefreshResult = {
5307
+ chats: { ...storedChats },
5308
+ permissionDeniedChatIds: [],
5309
+ failedChatIds: [],
5310
+ };
5311
+
5312
+ const tenantId: string | undefined = projectAuth?.workspaceProjectId;
5313
+
5314
+ const groupChats: Array<MicrosoftTeamsChat> = Object.values(
5315
+ storedChats,
5316
+ ).filter((chat: MicrosoftTeamsChat) => {
5317
+ return Boolean(chat && chat.id && chat.chatType === "groupChat");
5318
+ });
5319
+
5320
+ if (!tenantId || groupChats.length === 0) {
5321
+ return result;
5322
+ }
5323
+
5324
+ /*
5325
+ * One token for every lookup. Without one nothing can be read, and that
5326
+ * is a failure the caller must see — not a refresh that silently changed
5327
+ * nothing.
5328
+ */
5329
+ const accessToken: string = await this.getValidAccessToken({
5330
+ authToken: "",
5331
+ projectId: data.projectId,
5332
+ });
5333
+
5334
+ const updates: Record<string, MicrosoftTeamsChatNameUpdate> = {};
5335
+
5336
+ for (
5337
+ let index: number = 0;
5338
+ index < groupChats.length;
5339
+ index += MICROSOFT_TEAMS_CHAT_TOPIC_LOOKUP_CONCURRENCY
5340
+ ) {
5341
+ const batch: Array<MicrosoftTeamsChat> = groupChats.slice(
5342
+ index,
5343
+ index + MICROSOFT_TEAMS_CHAT_TOPIC_LOOKUP_CONCURRENCY,
5344
+ );
5345
+
5346
+ const lookups: Array<MicrosoftTeamsChatTopicLookup> = await Promise.all(
5347
+ batch.map((chat: MicrosoftTeamsChat) => {
5348
+ return this.getGroupChatTopicFromGraph({
5349
+ projectId: data.projectId,
5350
+ chatId: chat.id,
5351
+ accessToken: accessToken,
5352
+ });
5353
+ }),
5354
+ );
5355
+
5356
+ batch.forEach((chat: MicrosoftTeamsChat, batchIndex: number) => {
5357
+ const lookup: MicrosoftTeamsChatTopicLookup = lookups[batchIndex]!;
5358
+
5359
+ if (
5360
+ lookup.status === MicrosoftTeamsChatTopicLookupStatus.PermissionDenied
5361
+ ) {
5362
+ result.permissionDeniedChatIds.push(chat.id);
5363
+ return;
5364
+ }
5365
+
5366
+ if (lookup.status === MicrosoftTeamsChatTopicLookupStatus.Unknown) {
5367
+ result.failedChatIds.push(chat.id);
5368
+ return;
5369
+ }
5370
+
5371
+ const update: MicrosoftTeamsChatNameUpdate = this.getChatNameUpdate({
5372
+ chat: chat,
5373
+ lookup: lookup,
5374
+ });
5375
+
5376
+ if (update.name !== chat.name || update.topic !== chat.topic) {
5377
+ updates[chat.id] = update;
5378
+ }
5379
+ });
5380
+ }
5381
+
5382
+ if (Object.keys(updates).length > 0) {
5383
+ await this.renameChatsInProjectAuthTokens({
5384
+ tenantId: tenantId,
5385
+ chatNames: updates,
5386
+ });
5387
+ }
5388
+
5389
+ /*
5390
+ * What is stored now, whether or not anything was renamed: a chat
5391
+ * removed while names were being read is gone, and is not reported.
5392
+ */
5393
+ result.chats = await this.getChatsForProject({
5394
+ projectId: data.projectId,
5395
+ });
5396
+
5397
+ return result;
5398
+ }
5399
+
5400
+ // The name a stored group chat gets from a lookup that Graph answered.
5401
+ private static getChatNameUpdate(data: {
5402
+ chat: MicrosoftTeamsChat;
5403
+ lookup: MicrosoftTeamsChatTopicLookup;
5404
+ }): MicrosoftTeamsChatNameUpdate {
5405
+ const chat: MicrosoftTeamsChat = data.chat;
5406
+
5407
+ if (
5408
+ data.lookup.status === MicrosoftTeamsChatTopicLookupStatus.Found &&
5409
+ data.lookup.topic
5410
+ ) {
5411
+ return {
5412
+ name: this.getChatDisplayName({
5413
+ chatType: chat.chatType,
5414
+ topic: data.lookup.topic,
5415
+ memberNames: [],
5416
+ }),
5417
+ topic: data.lookup.topic,
5418
+ };
5419
+ }
5420
+
5421
+ // The chat has no name in Teams.
5422
+ if (chat.memberNames && chat.memberNames.length > 0) {
5423
+ return {
5424
+ name: this.getChatDisplayName({
5425
+ chatType: chat.chatType,
5426
+ memberNames: chat.memberNames,
5427
+ memberCount: chat.memberCount,
5428
+ }),
5429
+ };
5430
+ }
5431
+
5432
+ /*
5433
+ * No members to name it after. Keep the current name — unless it was the
5434
+ * Teams name that has just been removed.
5435
+ */
5436
+ return {
5437
+ name: chat.topic
5438
+ ? this.getChatDisplayName({ chatType: chat.chatType, memberNames: [] })
5439
+ : chat.name,
5440
+ };
5441
+ }
5442
+
5443
+ /*
5444
+ * Sets the name (and the Teams name it came from) of chats already stored
5445
+ * for a tenant, on every connected project. Only those fields are written,
5446
+ * onto each record as it is now — a chat removed or re-captured while names
5447
+ * were being looked up is neither resurrected nor rolled back.
5448
+ */
5449
+ @CaptureSpan()
5450
+ public static async renameChatsInProjectAuthTokens(data: {
5451
+ tenantId: string;
5452
+ chatNames: Record<string, MicrosoftTeamsChatNameUpdate>;
5453
+ }): Promise<void> {
5454
+ const projectAuths: Array<WorkspaceProjectAuthToken> =
5455
+ await WorkspaceProjectAuthTokenService.findBy({
5456
+ query: {
5457
+ workspaceType: WorkspaceType.MicrosoftTeams,
5458
+ workspaceProjectId: data.tenantId,
5459
+ },
5460
+ select: {
5461
+ _id: true,
5462
+ miscData: true,
5463
+ },
5464
+ limit: LIMIT_MAX,
5465
+ skip: 0,
5466
+ props: {
5467
+ isRoot: true,
5468
+ },
5469
+ });
5470
+
5471
+ for (const projectAuth of projectAuths) {
5472
+ const miscData: MicrosoftTeamsMiscData = {
5473
+ ...((projectAuth.miscData as MicrosoftTeamsMiscData) || {}),
5474
+ } as MicrosoftTeamsMiscData;
5475
+
5476
+ const availableChats: Record<string, MicrosoftTeamsChat> = {
5477
+ ...(miscData.availableChats || {}),
5478
+ };
5479
+
5480
+ let changed: boolean = false;
5481
+
5482
+ for (const [chatId, update] of Object.entries(data.chatNames)) {
5483
+ const existingChat: MicrosoftTeamsChat | undefined =
5484
+ availableChats[chatId];
5485
+
5486
+ if (
5487
+ !existingChat ||
5488
+ (existingChat.name === update.name &&
5489
+ existingChat.topic === update.topic)
5490
+ ) {
5491
+ continue;
5492
+ }
5493
+
5494
+ const renamedChat: MicrosoftTeamsChat = {
5495
+ ...existingChat,
5496
+ name: update.name,
5497
+ };
5498
+
5499
+ if (update.topic) {
5500
+ renamedChat.topic = update.topic;
5501
+ } else {
5502
+ delete renamedChat.topic;
5503
+ }
5504
+
5505
+ availableChats[chatId] = renamedChat;
5506
+ changed = true;
5507
+ }
5508
+
5509
+ if (!changed) {
5510
+ continue;
5511
+ }
5512
+
5513
+ miscData.availableChats = availableChats;
5514
+
5515
+ await WorkspaceProjectAuthTokenService.updateOneById({
5516
+ id: projectAuth.id!,
5517
+ data: {
5518
+ miscData: miscData,
5519
+ },
5520
+ props: {
5521
+ isRoot: true,
5522
+ },
5523
+ });
5524
+ }
5525
+ }
5526
+
4890
5527
  @CaptureSpan()
4891
5528
  public static async getChatsForProject(data: {
4892
5529
  projectId: ObjectID;