@oneuptime/common 14.0.9 → 14.0.10

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 (383) hide show
  1. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
  2. package/Models/DatabaseModels/CephCluster.ts +213 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +213 -0
  4. package/Models/DatabaseModels/DockerHost.ts +213 -0
  5. package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
  6. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  7. package/Models/DatabaseModels/Host.ts +213 -0
  8. package/Models/DatabaseModels/Index.ts +2 -0
  9. package/Models/DatabaseModels/PodmanHost.ts +213 -0
  10. package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
  11. package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
  12. package/Models/DatabaseModels/RunnerJob.ts +144 -0
  13. package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
  14. package/Server/API/AutoRemediationAPI.ts +392 -1
  15. package/Server/API/ResourceAiAccessAPI.ts +1669 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  18. package/Server/Infrastructure/Semaphore.ts +22 -0
  19. package/Server/Middleware/TelemetryIngest.ts +15 -5
  20. package/Server/Services/AnalyticsDatabaseService.ts +45 -1
  21. package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
  22. package/Server/Services/CephClusterService.ts +109 -1
  23. package/Server/Services/DatabaseServerService.ts +116 -1
  24. package/Server/Services/DockerHostService.ts +109 -1
  25. package/Server/Services/DockerSwarmClusterService.ts +113 -1
  26. package/Server/Services/HostService.ts +126 -4
  27. package/Server/Services/MetricRecordingRuleService.ts +47 -0
  28. package/Server/Services/PodmanHostService.ts +109 -1
  29. package/Server/Services/ProxmoxClusterService.ts +110 -1
  30. package/Server/Services/ResourceAiAccessService.ts +1439 -0
  31. package/Server/Services/ResourceAiAgentJobService.ts +202 -0
  32. package/Server/Services/ResourceAiAgentService.ts +2432 -0
  33. package/Server/Services/RunnerJobService.ts +611 -4
  34. package/Server/Services/TelemetryUsageBillingService.ts +28 -0
  35. package/Server/Services/TraceRecordingRuleService.ts +33 -0
  36. package/Server/Services/VMwareVCenterService.ts +110 -1
  37. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1434 -32
  38. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +935 -21
  39. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
  40. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
  41. package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
  42. package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
  43. package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
  44. package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
  45. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
  46. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +72 -2
  47. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
  48. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
  49. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
  50. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
  51. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
  52. package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
  53. package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
  54. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
  55. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
  56. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
  57. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
  58. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
  59. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
  60. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +366 -143
  61. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
  63. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
  64. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
  65. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
  66. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
  67. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +93 -0
  68. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
  69. package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
  70. package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
  71. package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
  72. package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
  73. package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
  74. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
  75. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
  76. package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
  77. package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
  78. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
  79. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
  80. package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
  81. package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
  82. package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
  83. package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
  84. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
  85. package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
  86. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
  87. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
  88. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
  89. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
  90. package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
  91. package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
  92. package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
  93. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
  94. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
  95. package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
  96. package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
  97. package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
  98. package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
  99. package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
  100. package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
  101. package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
  102. package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
  103. package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
  104. package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
  105. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
  106. package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
  107. package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
  108. package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
  109. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
  110. package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
  111. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
  112. package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
  113. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
  114. package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
  115. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
  116. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
  117. package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
  118. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
  119. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
  120. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
  121. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
  122. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
  123. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
  124. package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
  125. package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
  126. package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
  127. package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
  128. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -3
  129. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
  130. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
  131. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
  132. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
  133. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
  134. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
  135. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
  137. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
  138. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
  139. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
  140. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
  141. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
  142. package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
  143. package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
  144. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
  145. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
  146. package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
  147. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
  148. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
  149. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
  150. package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
  151. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
  152. package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
  153. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
  154. package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
  155. package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
  156. package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
  157. package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
  158. package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
  159. package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
  160. package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
  161. package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
  162. package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
  163. package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
  164. package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
  165. package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
  166. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
  167. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
  168. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
  169. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
  170. package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
  171. package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
  172. package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
  173. package/Types/AI/ResourceAiAccessApi.ts +140 -0
  174. package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
  175. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
  176. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
  177. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
  178. package/Types/Monitor/RumAlertTemplates.ts +351 -4
  179. package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
  180. package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
  181. package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
  182. package/Types/Runbook/RunbookStepType.ts +29 -0
  183. package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
  184. package/Utils/AI/InvestigationReport.ts +121 -15
  185. package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
  186. package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
  187. package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
  188. package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
  189. package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
  190. package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
  191. package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
  192. package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
  193. package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
  194. package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
  195. package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
  196. package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
  197. package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
  198. package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
  199. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  200. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  201. package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
  202. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  203. package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
  204. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  205. package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
  206. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
  208. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  209. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  210. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  211. package/build/dist/Models/DatabaseModels/Host.js +219 -0
  212. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  214. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
  216. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -0
  218. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  219. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
  220. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
  221. package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
  222. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  223. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
  224. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  225. package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
  226. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  227. package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
  228. package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
  234. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  235. package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
  236. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  237. package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  239. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
  240. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  241. package/build/dist/Server/Services/CephClusterService.js +104 -0
  242. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  243. package/build/dist/Server/Services/DatabaseServerService.js +99 -0
  244. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
  245. package/build/dist/Server/Services/DockerHostService.js +104 -0
  246. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  247. package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
  248. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  249. package/build/dist/Server/Services/HostService.js +114 -2
  250. package/build/dist/Server/Services/HostService.js.map +1 -1
  251. package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
  252. package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
  253. package/build/dist/Server/Services/PodmanHostService.js +104 -0
  254. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  255. package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
  256. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  257. package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
  258. package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
  259. package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
  260. package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
  261. package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
  262. package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
  263. package/build/dist/Server/Services/RunnerJobService.js +344 -5
  264. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  265. package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
  266. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  267. package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
  268. package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
  269. package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
  270. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  271. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1029 -30
  272. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  273. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +633 -28
  274. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  275. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
  276. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  277. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
  278. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
  279. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
  280. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
  281. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
  282. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
  283. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
  284. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
  285. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
  286. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
  287. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
  288. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
  289. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +50 -4
  290. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  291. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
  292. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  293. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
  294. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  295. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
  296. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  297. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
  298. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  299. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
  300. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  301. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
  302. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
  303. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
  304. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
  305. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
  306. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  307. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
  308. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  309. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
  310. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  311. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
  312. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  313. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
  314. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  315. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
  316. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  317. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +263 -110
  318. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  319. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
  320. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
  321. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
  322. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
  323. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
  324. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
  325. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
  326. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
  327. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
  328. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
  329. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
  330. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
  331. package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
  332. package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
  333. package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
  334. package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
  335. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +116 -29
  336. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  337. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
  338. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  339. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
  340. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  341. package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
  342. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  343. package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
  344. package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
  345. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
  346. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
  347. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
  348. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
  349. package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
  350. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  351. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
  352. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  353. package/build/dist/Utils/AI/InvestigationReport.js +71 -11
  354. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  355. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
  356. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
  357. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
  358. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
  359. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
  360. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
  361. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
  362. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
  363. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
  364. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
  365. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
  366. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
  367. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
  368. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
  369. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
  370. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
  371. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
  372. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
  373. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
  374. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
  375. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
  376. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
  377. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
  378. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
  379. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
  380. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
  381. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
  382. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
  383. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ import { JSONObject } from "../../../../Types/JSON";
2
+ import ErrorClass from "../../../../Types/Telemetry/ErrorClass";
3
+ import { ERROR_CLASS_ATTRIBUTE_KEY } from "../../../../Types/Telemetry/UnitOfWork";
4
+ import GlobalCache from "../../../Infrastructure/GlobalCache";
5
+ import InMemoryTTLCache from "../../../Infrastructure/InMemoryTTLCache";
6
+ import Redis from "../../../Infrastructure/Redis";
7
+ import logger, { LogAttributes } from "../../Logger";
8
+
9
+ /*
10
+ * Teams delivers an activity again when the bot was slow to answer it
11
+ * (documented: more than 15 seconds) and, in practice, when the bot answered
12
+ * it with an error. The redelivery carries the same activity id. Without a
13
+ * guard the user sees every reply twice, and a submitted form creates two
14
+ * incidents (issue #4111 showed each error bubble twice). Claiming the id
15
+ * before acting on an activity turns every delivery after the first into a
16
+ * no-op.
17
+ *
18
+ * The claim is shared through Redis, because a redelivery can reach another
19
+ * App instance, and kept in this process's memory as well. When Redis is
20
+ * disconnected the memory decides at once; when it is slow, after at most
21
+ * REDIS_CLAIM_TIMEOUT_IN_MS. Memory alone still covers a single instance.
22
+ */
23
+
24
+ const CLAIM_NAMESPACE: string = "microsoft-teams-inbound-activity";
25
+
26
+ // Redeliveries arrive within seconds; ten minutes leaves a wide margin.
27
+ const CLAIM_TTL_IN_SECONDS: number = 10 * 60;
28
+
29
+ // How long a Redis claim may take before this process's memory decides.
30
+ const REDIS_CLAIM_TIMEOUT_IN_MS: number = 2000;
31
+
32
+ // A Redis fallback is logged at most this often; each message would repeat it.
33
+ const FALLBACK_LOG_INTERVAL_IN_MS: number = 60 * 1000;
34
+
35
+ export default class MicrosoftTeamsActivityDeduplicator {
36
+ private static localClaims: InMemoryTTLCache<boolean> =
37
+ new InMemoryTTLCache<boolean>(10_000);
38
+
39
+ private static lastFallbackLoggedAt: number = 0;
40
+
41
+ /*
42
+ * The key an activity is claimed under: its conversation and its id. Null
43
+ * when the activity has no id, which Teams always sends.
44
+ */
45
+ public static getClaimKey(activity: JSONObject): string | null {
46
+ const activityId: string = (activity["id"] as string | undefined) || "";
47
+
48
+ if (!activityId) {
49
+ return null;
50
+ }
51
+
52
+ const conversationId: string =
53
+ ((activity["conversation"] as JSONObject | undefined)?.["id"] as
54
+ | string
55
+ | undefined) || "";
56
+
57
+ return `${conversationId}|${activityId}`;
58
+ }
59
+
60
+ /*
61
+ * True for the first delivery of an activity, false for a repeat. An
62
+ * activity without an id is always processed.
63
+ */
64
+ public static async claim(activity: JSONObject): Promise<boolean> {
65
+ const key: string | null = this.getClaimKey(activity);
66
+
67
+ if (!key) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * This process's memory is consulted whatever Redis says: a claim made
73
+ * here while Redis was down never reached Redis, so once Redis is back it
74
+ * would let a redelivery of that activity through.
75
+ */
76
+ const isClaimedHere: boolean = this.localClaims.has(key);
77
+
78
+ // A repeat leaves the claim alone, so it lapses with the Redis key.
79
+ if (!isClaimedHere) {
80
+ this.localClaims.set(key, true, CLAIM_TTL_IN_SECONDS * 1000);
81
+ }
82
+
83
+ // Asked even then, so that other App instances learn of the claim.
84
+ const claimedInRedis: boolean | null = await this.claimInRedis(key);
85
+
86
+ if (isClaimedHere) {
87
+ return false;
88
+ }
89
+
90
+ return claimedInRedis ?? true;
91
+ }
92
+
93
+ // The Redis answer, or null when Redis could not answer in time.
94
+ private static async claimInRedis(key: string): Promise<boolean | null> {
95
+ let timeout: ReturnType<typeof setTimeout> | undefined = undefined;
96
+
97
+ try {
98
+ return await Promise.race([
99
+ GlobalCache.setStringIfNotExists(CLAIM_NAMESPACE, key, "1", {
100
+ expiresInSeconds: CLAIM_TTL_IN_SECONDS,
101
+ }),
102
+ new Promise<null>((resolve: (value: null) => void) => {
103
+ timeout = setTimeout(() => {
104
+ this.logFallback(
105
+ `Redis did not answer within ${REDIS_CLAIM_TIMEOUT_IN_MS} ms`,
106
+ );
107
+ resolve(null);
108
+ }, REDIS_CLAIM_TIMEOUT_IN_MS);
109
+ }),
110
+ ]);
111
+ } catch (error) {
112
+ this.logFallback("Redis refused the claim", error);
113
+ return null;
114
+ } finally {
115
+ if (timeout) {
116
+ clearTimeout(timeout);
117
+ }
118
+ }
119
+ }
120
+
121
+ /*
122
+ * Falling back to memory means a redelivery that reaches another App
123
+ * instance is handled twice, which an operator should hear about. Logged at
124
+ * error level (warn is dropped at the default LOG_LEVEL) and at most once a
125
+ * minute. A process that never had a Redis client (a script, a test) has no
126
+ * other instance to share with, so it only logs at debug.
127
+ *
128
+ * It never throws: it runs from the claim's catch and from its timeout, and
129
+ * a throw there would lose the claim, or the reply, over a log line.
130
+ */
131
+ private static logFallback(reason: string, error?: unknown): void {
132
+ try {
133
+ const now: number = Date.now();
134
+
135
+ if (
136
+ !Redis.getClient() ||
137
+ now - this.lastFallbackLoggedAt < FALLBACK_LOG_INTERVAL_IN_MS
138
+ ) {
139
+ logger.debug(
140
+ `Microsoft Teams activity dedupe is using this process's memory: ${reason}`,
141
+ );
142
+ return;
143
+ }
144
+
145
+ this.lastFallbackLoggedAt = now;
146
+
147
+ const attributes: LogAttributes = {
148
+ [ERROR_CLASS_ATTRIBUTE_KEY]: ErrorClass.Infrastructure,
149
+ };
150
+
151
+ logger.error(
152
+ `Microsoft Teams activity dedupe fell back to this process's memory (${reason}); a Teams redelivery that reaches another App instance may be handled twice.`,
153
+ attributes,
154
+ );
155
+
156
+ if (error) {
157
+ logger.error(error, attributes);
158
+ }
159
+ } catch {
160
+ // Nothing to do: the claim goes on from memory either way.
161
+ }
162
+ }
163
+ }
@@ -0,0 +1,396 @@
1
+ import { JSONObject } from "../../../../Types/JSON";
2
+ import ObjectID from "../../../../Types/ObjectID";
3
+ import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
4
+ import Monitor from "../../../../Models/DatabaseModels/Monitor";
5
+ import MonitorStatus from "../../../../Models/DatabaseModels/MonitorStatus";
6
+ import Label from "../../../../Models/DatabaseModels/Label";
7
+ import IncidentSeverity from "../../../../Models/DatabaseModels/IncidentSeverity";
8
+ import OnCallDutyPolicy from "../../../../Models/DatabaseModels/OnCallDutyPolicy";
9
+ import MonitorService from "../../../Services/MonitorService";
10
+ import MonitorStatusService from "../../../Services/MonitorStatusService";
11
+ import LabelService from "../../../Services/LabelService";
12
+ import IncidentSeverityService from "../../../Services/IncidentSeverityService";
13
+ import OnCallDutyPolicyService from "../../../Services/OnCallDutyPolicyService";
14
+ import { truncateToLength } from "../../Database/TruncateColumnValue";
15
+ import MicrosoftTeamsMessageSize from "./MicrosoftTeamsMessageSize";
16
+
17
+ /*
18
+ * The choice lists of the "create incident" and "create maintenance" cards.
19
+ *
20
+ * Those cards used to list every monitor, label and on-call policy of the
21
+ * project (up to 10,000 of each), which Microsoft Teams refuses as too large
22
+ * once a project has a few hundred of them (issue #4111). Each list is now
23
+ * read up to a cap (monitors, labels and on-call policies in name order,
24
+ * severities and monitor statuses in their own order), and fitCardToBudget()
25
+ * shortens the long lists until the card fits a size budget. Whatever is
26
+ * left off is named on the card, so the user knows to add it in OneUptime.
27
+ */
28
+
29
+ // A type, not an interface, so a list of them is a JSONValue on a card.
30
+ export type MicrosoftTeamsCardChoice = {
31
+ title: string;
32
+ value: string;
33
+ };
34
+
35
+ // The choices of one list, and how many records the project has in all.
36
+ export interface MicrosoftTeamsCardChoiceList {
37
+ choices: Array<MicrosoftTeamsCardChoice>;
38
+ totalCount: number;
39
+ }
40
+
41
+ export interface MicrosoftTeamsFittedCard<TKey extends string> {
42
+ card: JSONObject;
43
+ // How many choices of each list the card shows.
44
+ shownCounts: Record<TKey, number>;
45
+ // False when the card is over budget even with every trimmable list empty.
46
+ fitsBudget: boolean;
47
+ }
48
+
49
+ /*
50
+ * Most choices read for one list. The size budget, not these caps, decides
51
+ * how many a card shows; the caps only keep the reads small. More than a
52
+ * couple of hundred entries is not a usable dropdown anyway.
53
+ */
54
+ export const MICROSOFT_TEAMS_MAX_MONITOR_CHOICES: number = 250;
55
+ export const MICROSOFT_TEAMS_MAX_LABEL_CHOICES: number = 100;
56
+ export const MICROSOFT_TEAMS_MAX_ON_CALL_POLICY_CHOICES: number = 100;
57
+ export const MICROSOFT_TEAMS_MAX_SEVERITY_CHOICES: number = 50;
58
+ export const MICROSOFT_TEAMS_MAX_MONITOR_STATUS_CHOICES: number = 50;
59
+
60
+ // Longer names are cut: a Teams dropdown shows about this much of a row.
61
+ export const MICROSOFT_TEAMS_MAX_CHOICE_TITLE_LENGTH: number = 80;
62
+
63
+ type NamedRecord = {
64
+ _id?: string | undefined;
65
+ name?: string | undefined;
66
+ };
67
+
68
+ export default class MicrosoftTeamsCardChoices {
69
+ // Rows to choices, skipping rows without a name or id.
70
+ public static toChoices(
71
+ rows: Array<NamedRecord>,
72
+ ): Array<MicrosoftTeamsCardChoice> {
73
+ const choices: Array<MicrosoftTeamsCardChoice> = [];
74
+
75
+ for (const row of rows) {
76
+ const title: string = (row.name || "").trim();
77
+ const value: string = row._id?.toString() || "";
78
+
79
+ if (!title || !value) {
80
+ continue;
81
+ }
82
+
83
+ choices.push({
84
+ title:
85
+ title.length > MICROSOFT_TEAMS_MAX_CHOICE_TITLE_LENGTH
86
+ ? truncateToLength(
87
+ title,
88
+ MICROSOFT_TEAMS_MAX_CHOICE_TITLE_LENGTH - 1,
89
+ ) + "…"
90
+ : title,
91
+ value: value,
92
+ });
93
+ }
94
+
95
+ return choices;
96
+ }
97
+
98
+ /*
99
+ * Builds the card from every choice it was given, then, while it is over
100
+ * the budget, shortens the longest trimmable list by a quarter (at least by
101
+ * one). The longest list goes first because it is what makes the card big,
102
+ * and shortening it by a share keeps the number of rebuilds small even for
103
+ * hundreds of choices. Lists that are not trimmable are always shown whole.
104
+ */
105
+ public static fitCardToBudget<TKey extends string>(data: {
106
+ lists: Record<TKey, MicrosoftTeamsCardChoiceList>;
107
+ trimmableKeys: ReadonlyArray<TKey>;
108
+ budgetInBytes: number;
109
+ buildCard: (
110
+ shownLists: Record<TKey, MicrosoftTeamsCardChoiceList>,
111
+ ) => JSONObject;
112
+ }): MicrosoftTeamsFittedCard<TKey> {
113
+ const keys: Array<TKey> = Object.keys(data.lists) as Array<TKey>;
114
+ const shownCounts: Record<TKey, number> = {} as Record<TKey, number>;
115
+
116
+ for (const key of keys) {
117
+ shownCounts[key] = data.lists[key].choices.length;
118
+ }
119
+
120
+ // No budget: leave every trimmable list off in one go.
121
+ if (data.budgetInBytes <= 0) {
122
+ for (const key of data.trimmableKeys) {
123
+ shownCounts[key] = 0;
124
+ }
125
+ }
126
+
127
+ const build: () => JSONObject = (): JSONObject => {
128
+ const shownLists: Record<TKey, MicrosoftTeamsCardChoiceList> =
129
+ {} as Record<TKey, MicrosoftTeamsCardChoiceList>;
130
+
131
+ for (const key of keys) {
132
+ shownLists[key] = {
133
+ choices: data.lists[key].choices.slice(0, shownCounts[key]),
134
+ totalCount: data.lists[key].totalCount,
135
+ };
136
+ }
137
+
138
+ return data.buildCard(shownLists);
139
+ };
140
+
141
+ let card: JSONObject = build();
142
+
143
+ while (
144
+ MicrosoftTeamsMessageSize.getSizeInBytes(card) > data.budgetInBytes
145
+ ) {
146
+ let longestKey: TKey | null = null;
147
+
148
+ for (const key of data.trimmableKeys) {
149
+ if (
150
+ shownCounts[key] > 0 &&
151
+ (longestKey === null || shownCounts[key] > shownCounts[longestKey])
152
+ ) {
153
+ longestKey = key;
154
+ }
155
+ }
156
+
157
+ if (longestKey === null) {
158
+ return { card: card, shownCounts: shownCounts, fitsBudget: false };
159
+ }
160
+
161
+ const count: number = shownCounts[longestKey];
162
+ shownCounts[longestKey] = Math.min(count - 1, Math.floor(count * 0.75));
163
+ card = build();
164
+ }
165
+
166
+ return { card: card, shownCounts: shownCounts, fitsBudget: true };
167
+ }
168
+
169
+ // A small line of text on a card, such as what a list leaves out.
170
+ public static buildNoteElement(text: string): JSONObject {
171
+ return {
172
+ type: "TextBlock",
173
+ text: text,
174
+ wrap: true,
175
+ isSubtle: true,
176
+ size: "Small",
177
+ spacing: "Small",
178
+ };
179
+ }
180
+
181
+ // The note element for a list the card could not show in full, or null.
182
+ public static buildNotShownNoteElement(data: {
183
+ list: MicrosoftTeamsCardChoiceList;
184
+ pluralNoun: string;
185
+ addLaterHint: string;
186
+ }): JSONObject | null {
187
+ const note: string | null = this.getNotShownNote(data);
188
+
189
+ return note ? this.buildNoteElement(note) : null;
190
+ }
191
+
192
+ // The button a card offers when it had to leave something off.
193
+ public static buildCreateInOneUptimeAction(url: string): JSONObject {
194
+ return {
195
+ type: "Action.OpenUrl",
196
+ title: "Create in OneUptime",
197
+ url: url,
198
+ };
199
+ }
200
+
201
+ /*
202
+ * The line shown under a list the card could not show in full, or null
203
+ * when it shows every record.
204
+ */
205
+ public static getNotShownNote(data: {
206
+ list: MicrosoftTeamsCardChoiceList;
207
+ pluralNoun: string; // e.g. "monitors"
208
+ addLaterHint: string; // e.g. "You can add them to the incident in OneUptime after it is created."
209
+ }): string | null {
210
+ const shownCount: number = data.list.choices.length;
211
+ const totalCount: number = Math.max(data.list.totalCount, shownCount);
212
+
213
+ if (shownCount >= totalCount) {
214
+ return null;
215
+ }
216
+
217
+ if (shownCount === 0) {
218
+ return `This project has ${totalCount} ${data.pluralNoun}, too many to list in Microsoft Teams. ${data.addLaterHint}`;
219
+ }
220
+
221
+ return `Showing the first ${shownCount} of ${totalCount} ${data.pluralNoun}, by name. ${data.addLaterHint}`;
222
+ }
223
+
224
+ public static async getMonitorChoices(
225
+ projectId: ObjectID,
226
+ ): Promise<MicrosoftTeamsCardChoiceList> {
227
+ const monitors: Array<Monitor> = await MonitorService.findBy({
228
+ query: {
229
+ projectId: projectId,
230
+ },
231
+ select: {
232
+ _id: true,
233
+ name: true,
234
+ },
235
+ sort: {
236
+ name: SortOrder.Ascending,
237
+ },
238
+ limit: MICROSOFT_TEAMS_MAX_MONITOR_CHOICES,
239
+ skip: 0,
240
+ props: {
241
+ isRoot: true,
242
+ },
243
+ });
244
+
245
+ return {
246
+ choices: this.toChoices(monitors),
247
+ totalCount:
248
+ monitors.length < MICROSOFT_TEAMS_MAX_MONITOR_CHOICES
249
+ ? monitors.length
250
+ : (
251
+ await MonitorService.countBy({
252
+ query: {
253
+ projectId: projectId,
254
+ },
255
+ props: {
256
+ isRoot: true,
257
+ },
258
+ })
259
+ ).toNumber(),
260
+ };
261
+ }
262
+
263
+ public static async getMonitorStatusChoices(
264
+ projectId: ObjectID,
265
+ ): Promise<MicrosoftTeamsCardChoiceList> {
266
+ const monitorStatuses: Array<MonitorStatus> =
267
+ await MonitorStatusService.findBy({
268
+ query: {
269
+ projectId: projectId,
270
+ },
271
+ select: {
272
+ _id: true,
273
+ name: true,
274
+ },
275
+ sort: {
276
+ priority: SortOrder.Ascending,
277
+ },
278
+ limit: MICROSOFT_TEAMS_MAX_MONITOR_STATUS_CHOICES,
279
+ skip: 0,
280
+ props: {
281
+ isRoot: true,
282
+ },
283
+ });
284
+
285
+ const choices: Array<MicrosoftTeamsCardChoice> =
286
+ this.toChoices(monitorStatuses);
287
+
288
+ return { choices: choices, totalCount: choices.length };
289
+ }
290
+
291
+ public static async getLabelChoices(
292
+ projectId: ObjectID,
293
+ ): Promise<MicrosoftTeamsCardChoiceList> {
294
+ const labels: Array<Label> = await LabelService.findBy({
295
+ query: {
296
+ projectId: projectId,
297
+ },
298
+ select: {
299
+ _id: true,
300
+ name: true,
301
+ },
302
+ sort: {
303
+ name: SortOrder.Ascending,
304
+ },
305
+ limit: MICROSOFT_TEAMS_MAX_LABEL_CHOICES,
306
+ skip: 0,
307
+ props: {
308
+ isRoot: true,
309
+ },
310
+ });
311
+
312
+ return {
313
+ choices: this.toChoices(labels),
314
+ totalCount:
315
+ labels.length < MICROSOFT_TEAMS_MAX_LABEL_CHOICES
316
+ ? labels.length
317
+ : (
318
+ await LabelService.countBy({
319
+ query: {
320
+ projectId: projectId,
321
+ },
322
+ props: {
323
+ isRoot: true,
324
+ },
325
+ })
326
+ ).toNumber(),
327
+ };
328
+ }
329
+
330
+ public static async getIncidentSeverityChoices(
331
+ projectId: ObjectID,
332
+ ): Promise<MicrosoftTeamsCardChoiceList> {
333
+ const severities: Array<IncidentSeverity> =
334
+ await IncidentSeverityService.findBy({
335
+ query: {
336
+ projectId: projectId,
337
+ },
338
+ select: {
339
+ _id: true,
340
+ name: true,
341
+ },
342
+ sort: {
343
+ order: SortOrder.Ascending,
344
+ },
345
+ limit: MICROSOFT_TEAMS_MAX_SEVERITY_CHOICES,
346
+ skip: 0,
347
+ props: {
348
+ isRoot: true,
349
+ },
350
+ });
351
+
352
+ const choices: Array<MicrosoftTeamsCardChoice> = this.toChoices(severities);
353
+
354
+ return { choices: choices, totalCount: choices.length };
355
+ }
356
+
357
+ public static async getOnCallDutyPolicyChoices(
358
+ projectId: ObjectID,
359
+ ): Promise<MicrosoftTeamsCardChoiceList> {
360
+ const policies: Array<OnCallDutyPolicy> =
361
+ await OnCallDutyPolicyService.findBy({
362
+ query: {
363
+ projectId: projectId,
364
+ },
365
+ select: {
366
+ _id: true,
367
+ name: true,
368
+ },
369
+ sort: {
370
+ name: SortOrder.Ascending,
371
+ },
372
+ limit: MICROSOFT_TEAMS_MAX_ON_CALL_POLICY_CHOICES,
373
+ skip: 0,
374
+ props: {
375
+ isRoot: true,
376
+ },
377
+ });
378
+
379
+ return {
380
+ choices: this.toChoices(policies),
381
+ totalCount:
382
+ policies.length < MICROSOFT_TEAMS_MAX_ON_CALL_POLICY_CHOICES
383
+ ? policies.length
384
+ : (
385
+ await OnCallDutyPolicyService.countBy({
386
+ query: {
387
+ projectId: projectId,
388
+ },
389
+ props: {
390
+ isRoot: true,
391
+ },
392
+ })
393
+ ).toNumber(),
394
+ };
395
+ }
396
+ }