@oneuptime/common 12.0.3 → 12.0.5

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 (516) hide show
  1. package/Models/DatabaseModels/AIRun.ts +38 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +30 -0
  3. package/Models/DatabaseModels/CephCluster.ts +14 -0
  4. package/Models/DatabaseModels/CodeRepository.ts +14 -6
  5. package/Models/DatabaseModels/Dashboard.ts +28 -0
  6. package/Models/DatabaseModels/DockerHost.ts +14 -0
  7. package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
  8. package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
  9. package/Models/DatabaseModels/Incident.ts +2 -0
  10. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  11. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  12. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  13. package/Models/DatabaseModels/IncidentFeed.ts +30 -0
  14. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  15. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +14 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
  18. package/Models/DatabaseModels/LogSavedView.ts +33 -0
  19. package/Models/DatabaseModels/NetworkDevice.ts +14 -0
  20. package/Models/DatabaseModels/NetworkInterface.ts +18 -0
  21. package/Models/DatabaseModels/Project.ts +247 -11
  22. package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
  23. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  24. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  25. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  26. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
  27. package/Models/DatabaseModels/Service.ts +30 -0
  28. package/Models/DatabaseModels/StatusPage.ts +28 -0
  29. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  30. package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
  31. package/Models/DatabaseModels/User.ts +30 -0
  32. package/Server/API/AIAgentDataAPI.ts +75 -55
  33. package/Server/API/AIInvestigationAPI.ts +175 -17
  34. package/Server/API/DashboardAPI.ts +429 -22
  35. package/Server/API/GitHubAPI.ts +119 -283
  36. package/Server/API/StatusPageAPI.ts +38 -19
  37. package/Server/API/UserAPI.ts +263 -1
  38. package/Server/EnvironmentConfig.ts +23 -3
  39. package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
  40. package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
  41. package/Server/Infrastructure/GlobalCache.ts +37 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  53. package/Server/Services/AIRunService.ts +78 -10
  54. package/Server/Services/AIService.ts +94 -22
  55. package/Server/Services/AlertFeedService.ts +5 -0
  56. package/Server/Services/AnalyticsDatabaseService.ts +101 -1
  57. package/Server/Services/CodeRepositoryService.ts +105 -2
  58. package/Server/Services/DatabaseService.ts +227 -3
  59. package/Server/Services/IncidentFeedService.ts +5 -0
  60. package/Server/Services/LlmLogService.ts +46 -2
  61. package/Server/Services/OpenTelemetryIngestService.ts +230 -26
  62. package/Server/Services/UserService.ts +184 -0
  63. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
  64. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
  65. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
  66. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
  67. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
  68. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
  69. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
  70. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
  71. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
  72. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
  73. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
  74. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
  75. package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
  76. package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
  77. package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
  78. package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
  79. package/Server/Utils/AI/SRE/README.md +1 -1
  80. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
  81. package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
  82. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
  83. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
  84. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
  85. package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
  86. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
  87. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
  88. package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
  89. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  90. package/Server/Utils/PasswordHash.ts +330 -0
  91. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
  92. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
  93. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
  94. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
  95. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
  96. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
  97. package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
  98. package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
  99. package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
  100. package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
  101. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
  102. package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
  103. package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
  104. package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
  105. package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
  106. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
  107. package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
  108. package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
  109. package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
  110. package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
  111. package/Tests/Server/API/Helpers.ts +6 -1
  112. package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
  113. package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
  114. package/Tests/Server/Infrastructure/GlobalCache.test.ts +128 -0
  115. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
  116. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
  117. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
  118. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
  119. package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
  120. package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
  121. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
  122. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +30 -1
  123. package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
  124. package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
  125. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +880 -0
  126. package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
  127. package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
  128. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
  129. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
  130. package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
  131. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
  132. package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
  133. package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
  134. package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
  135. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
  136. package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
  137. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
  138. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
  139. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
  140. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
  141. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
  142. package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
  143. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
  144. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
  145. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
  146. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
  147. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
  148. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
  149. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
  150. package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
  151. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
  152. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
  153. package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
  154. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
  155. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
  156. package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
  157. package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
  158. package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
  159. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
  160. package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
  161. package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
  162. package/Tests/Server/Utils/PasswordHash.test.ts +585 -0
  163. package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
  164. package/Tests/Types/Database/ColumnLength.test.ts +7 -1
  165. package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
  166. package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
  167. package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
  168. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
  169. package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
  170. package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
  171. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
  172. package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
  173. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
  174. package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
  175. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
  177. package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
  178. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
  179. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
  180. package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
  181. package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
  182. package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
  183. package/Tests/Types/Permission.test.ts +137 -0
  184. package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
  185. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
  186. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
  187. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
  188. package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
  189. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
  190. package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
  191. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
  192. package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
  193. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
  194. package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
  195. package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
  196. package/Tests/UI/Utils/Project.test.ts +31 -0
  197. package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
  198. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
  199. package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
  200. package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
  201. package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
  202. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
  203. package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
  204. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
  205. package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
  206. package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
  207. package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
  208. package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
  209. package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
  210. package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
  211. package/Types/AI/CodeFixTaskContext.ts +63 -3
  212. package/Types/AI/CodeFixTaskType.ts +3 -3
  213. package/Types/Database/ColumnLength.ts +9 -1
  214. package/Types/Database/TableColumn.ts +11 -0
  215. package/Types/Database/UnsynchronizedIndex.ts +48 -0
  216. package/Types/HashedString.ts +140 -4
  217. package/Types/Monitor/CriteriaFilter.ts +4 -0
  218. package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
  219. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
  220. package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
  221. package/Types/Monitor/MonitorMetricType.ts +8 -0
  222. package/Types/Monitor/MonitorStep.ts +10 -1
  223. package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
  224. package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
  225. package/Types/Permission.ts +23 -175
  226. package/Types/Probe/ProbeMonitorResponse.ts +6 -0
  227. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
  228. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
  229. package/UI/Components/ErrorBoundary.tsx +138 -11
  230. package/UI/Components/Feed/FeedItem.tsx +9 -2
  231. package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
  232. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  233. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
  234. package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
  235. package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
  236. package/UI/Components/Navbar/NavBar.tsx +12 -2
  237. package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
  238. package/UI/Utils/DownloadFile.ts +16 -8
  239. package/UI/Utils/ErrorSupportBundle.ts +805 -0
  240. package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
  241. package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
  242. package/UI/Utils/Project.ts +4 -0
  243. package/UI/Utils/StatusPage.ts +8 -2
  244. package/UI/Utils/UseDashboardGridDnd.ts +917 -0
  245. package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
  246. package/Utils/Dashboard/GridLayout.ts +523 -0
  247. package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
  248. package/Utils/Monitor/MonitorMetricType.ts +44 -2
  249. package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
  250. package/Utils/StatusPage/GroupTree.ts +157 -66
  251. package/Utils/StatusPage/ResourceUptime.ts +37 -2
  252. package/Utils/TeamMembersByProject.ts +237 -0
  253. package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
  254. package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
  255. package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
  256. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  257. package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
  258. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  259. package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
  260. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  261. package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
  262. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  263. package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
  264. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  265. package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
  266. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  267. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
  268. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  269. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
  270. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  271. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  272. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  273. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  274. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  275. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  276. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  278. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  279. package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
  280. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  282. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  284. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
  286. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
  288. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
  290. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
  292. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
  294. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/Project.js +257 -13
  296. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
  298. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  300. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  302. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  304. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
  306. package/build/dist/Models/DatabaseModels/Service.js +28 -1
  307. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
  309. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  311. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
  313. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/User.js +32 -0
  315. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  316. package/build/dist/Server/API/AIAgentDataAPI.js +49 -48
  317. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  318. package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
  319. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  320. package/build/dist/Server/API/DashboardAPI.js +312 -15
  321. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  322. package/build/dist/Server/API/GitHubAPI.js +94 -167
  323. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  324. package/build/dist/Server/API/StatusPageAPI.js +29 -11
  325. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  326. package/build/dist/Server/API/UserAPI.js +187 -2
  327. package/build/dist/Server/API/UserAPI.js.map +1 -1
  328. package/build/dist/Server/EnvironmentConfig.js +21 -3
  329. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  330. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
  331. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  332. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
  333. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  334. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  335. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
  353. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
  354. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
  355. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
  356. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  357. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  358. package/build/dist/Server/Services/AIRunService.js +58 -12
  359. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  360. package/build/dist/Server/Services/AIService.js +74 -21
  361. package/build/dist/Server/Services/AIService.js.map +1 -1
  362. package/build/dist/Server/Services/AlertFeedService.js +3 -0
  363. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  364. package/build/dist/Server/Services/AnalyticsDatabaseService.js +86 -2
  365. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  366. package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
  367. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  368. package/build/dist/Server/Services/DatabaseService.js +180 -3
  369. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  370. package/build/dist/Server/Services/IncidentFeedService.js +3 -0
  371. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  372. package/build/dist/Server/Services/LlmLogService.js +22 -1
  373. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  374. package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
  375. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  376. package/build/dist/Server/Services/UserService.js +165 -0
  377. package/build/dist/Server/Services/UserService.js.map +1 -1
  378. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  379. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  380. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
  381. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
  382. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
  383. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  384. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
  385. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  386. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
  387. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  388. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
  389. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  390. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
  391. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  392. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
  393. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  394. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
  395. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
  396. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
  397. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  398. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
  399. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  400. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
  401. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  402. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
  403. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
  404. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
  405. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  406. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
  407. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
  408. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
  409. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
  410. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
  411. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
  412. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
  413. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
  414. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
  415. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  416. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
  417. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  418. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
  419. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  420. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
  421. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
  422. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
  423. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  424. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
  425. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  426. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  427. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  429. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  430. package/build/dist/Server/Utils/PasswordHash.js +258 -0
  431. package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
  432. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
  433. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
  434. package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
  435. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  436. package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
  437. package/build/dist/Types/Database/ColumnLength.js +9 -1
  438. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  439. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  440. package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
  441. package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
  442. package/build/dist/Types/HashedString.js +96 -5
  443. package/build/dist/Types/HashedString.js.map +1 -1
  444. package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
  445. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  446. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
  447. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
  448. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
  449. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  450. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  451. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  452. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  453. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
  455. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  456. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
  457. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
  458. package/build/dist/Types/Permission.js +23 -155
  459. package/build/dist/Types/Permission.js.map +1 -1
  460. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
  461. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  462. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
  463. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  464. package/build/dist/UI/Components/ErrorBoundary.js +67 -8
  465. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  466. package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
  467. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  468. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
  469. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  470. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  471. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  472. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
  473. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  474. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
  475. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  476. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
  477. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  478. package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
  479. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  480. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
  481. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  482. package/build/dist/UI/Utils/DownloadFile.js +15 -8
  483. package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
  484. package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
  485. package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
  486. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
  487. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  488. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
  489. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
  490. package/build/dist/UI/Utils/Project.js +3 -0
  491. package/build/dist/UI/Utils/Project.js.map +1 -1
  492. package/build/dist/UI/Utils/StatusPage.js +4 -4
  493. package/build/dist/UI/Utils/StatusPage.js.map +1 -1
  494. package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
  495. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
  496. package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
  497. package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
  498. package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
  499. package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
  500. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
  501. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
  502. package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
  503. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  504. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
  505. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
  506. package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
  507. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
  508. package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
  509. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  510. package/build/dist/Utils/TeamMembersByProject.js +145 -0
  511. package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
  512. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
  513. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
  514. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
  515. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
  516. package/package.json +1 -1
@@ -10,6 +10,7 @@ import IncidentFeed, {
10
10
  import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
11
11
  import ObjectID from "../../../../Types/ObjectID";
12
12
  import { afterEach, describe, expect, it } from "@jest/globals";
13
+ import { FindOperator } from "typeorm";
13
14
 
14
15
  /*
15
16
  * The one reader of the analysis an AI investigation posted.
@@ -31,6 +32,9 @@ const INCIDENT_ID: ObjectID = new ObjectID(
31
32
  "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
32
33
  );
33
34
  const ALERT_ID: ObjectID = new ObjectID("dddddddd-dddd-4ddd-8ddd-dddddddddddd");
35
+ const AI_RUN_ID: ObjectID = new ObjectID(
36
+ "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
37
+ );
34
38
 
35
39
  function incidentFeedItem(markdown: string | null): IncidentFeed {
36
40
  return {
@@ -44,6 +48,23 @@ function alertFeedItem(markdown: string | null): AlertFeed {
44
48
  } as unknown as AlertFeed;
45
49
  }
46
50
 
51
+ interface RawFindOperatorInternals {
52
+ _getSql: (columnName: string) => string;
53
+ _objectLiteralParameters: Record<string, unknown>;
54
+ }
55
+
56
+ function expectCreatedAtCutoff(
57
+ createdAtFilter: unknown,
58
+ expectedCutoff: Date,
59
+ ): void {
60
+ expect(createdAtFilter).toBeInstanceOf(FindOperator);
61
+
62
+ const raw: RawFindOperatorInternals =
63
+ createdAtFilter as RawFindOperatorInternals;
64
+ expect(raw._getSql("COLUMN")).toContain("COLUMN >=");
65
+ expect(Object.values(raw._objectLiteralParameters)).toEqual([expectedCutoff]);
66
+ }
67
+
47
68
  describe("PostedRootCause.getForIncident", () => {
48
69
  afterEach(() => {
49
70
  jest.restoreAllMocks();
@@ -85,6 +106,73 @@ describe("PostedRootCause.getForIncident", () => {
85
106
  }),
86
107
  }),
87
108
  );
109
+ const query: Record<string, unknown> = find.mock.calls[0]![0]
110
+ .query as Record<string, unknown>;
111
+ expect(Object.prototype.hasOwnProperty.call(query, "createdAt")).toBe(
112
+ false,
113
+ );
114
+ expect(Object.prototype.hasOwnProperty.call(query, "aiRunId")).toBe(false);
115
+ });
116
+
117
+ it("can select the RootCause explicitly owned by one investigation run", async () => {
118
+ const find: jest.SpyInstance = jest
119
+ .spyOn(IncidentFeedService, "findOneBy")
120
+ .mockResolvedValue(null);
121
+
122
+ await PostedRootCause.getForIncident(INCIDENT_ID, {
123
+ aiRunId: AI_RUN_ID,
124
+ });
125
+
126
+ expect(find).toHaveBeenCalledWith(
127
+ expect.objectContaining({
128
+ query: expect.objectContaining({
129
+ incidentId: INCIDENT_ID,
130
+ incidentFeedEventType: IncidentFeedEventType.RootCause,
131
+ aiRunId: AI_RUN_ID,
132
+ }),
133
+ }),
134
+ );
135
+ });
136
+
137
+ it("can restrict an upgrade lookup to rows without an AI run association", async () => {
138
+ const find: jest.SpyInstance = jest
139
+ .spyOn(IncidentFeedService, "findOneBy")
140
+ .mockResolvedValue(null);
141
+
142
+ await PostedRootCause.getForIncident(INCIDENT_ID, {
143
+ withoutAIRunId: true,
144
+ });
145
+
146
+ const aiRunIdFilter: unknown = find.mock.calls[0]![0].query.aiRunId;
147
+ expect(aiRunIdFilter).toBeInstanceOf(FindOperator);
148
+ expect(
149
+ (aiRunIdFilter as RawFindOperatorInternals)._getSql("COLUMN"),
150
+ ).toContain("COLUMN IS NULL");
151
+ });
152
+
153
+ it("can scope the RootCause item to feed rows created by this run", async () => {
154
+ const runCompletedAt: Date = new Date("2026-08-07T10:00:00.000Z");
155
+ const find: jest.SpyInstance = jest
156
+ .spyOn(IncidentFeedService, "findOneBy")
157
+ .mockResolvedValue(null);
158
+
159
+ await PostedRootCause.getForIncident(INCIDENT_ID, {
160
+ createdAtOrAfter: runCompletedAt,
161
+ });
162
+
163
+ expect(find).toHaveBeenCalledWith(
164
+ expect.objectContaining({
165
+ query: expect.objectContaining({
166
+ incidentId: INCIDENT_ID,
167
+ incidentFeedEventType: IncidentFeedEventType.RootCause,
168
+ createdAt: expect.any(FindOperator),
169
+ }),
170
+ }),
171
+ );
172
+ expectCreatedAtCutoff(
173
+ find.mock.calls[0]![0].query.createdAt,
174
+ runCompletedAt,
175
+ );
88
176
  });
89
177
 
90
178
  it("returns null when no analysis has been posted", async () => {
@@ -166,6 +254,57 @@ describe("PostedRootCause.getForAlert", () => {
166
254
  }),
167
255
  }),
168
256
  );
257
+ const query: Record<string, unknown> = find.mock.calls[0]![0]
258
+ .query as Record<string, unknown>;
259
+ expect(Object.prototype.hasOwnProperty.call(query, "createdAt")).toBe(
260
+ false,
261
+ );
262
+ expect(Object.prototype.hasOwnProperty.call(query, "aiRunId")).toBe(false);
263
+ });
264
+
265
+ it("can select the RootCause explicitly owned by one alert investigation", async () => {
266
+ const find: jest.SpyInstance = jest
267
+ .spyOn(AlertFeedService, "findOneBy")
268
+ .mockResolvedValue(null);
269
+
270
+ await PostedRootCause.getForAlert(ALERT_ID, {
271
+ aiRunId: AI_RUN_ID,
272
+ });
273
+
274
+ expect(find).toHaveBeenCalledWith(
275
+ expect.objectContaining({
276
+ query: expect.objectContaining({
277
+ alertId: ALERT_ID,
278
+ alertFeedEventType: AlertFeedEventType.RootCause,
279
+ aiRunId: AI_RUN_ID,
280
+ }),
281
+ }),
282
+ );
283
+ });
284
+
285
+ it("can scope the RootCause item to alert feed rows created by this run", async () => {
286
+ const runCompletedAt: Date = new Date("2026-08-07T11:00:00.000Z");
287
+ const find: jest.SpyInstance = jest
288
+ .spyOn(AlertFeedService, "findOneBy")
289
+ .mockResolvedValue(null);
290
+
291
+ await PostedRootCause.getForAlert(ALERT_ID, {
292
+ createdAtOrAfter: runCompletedAt,
293
+ });
294
+
295
+ expect(find).toHaveBeenCalledWith(
296
+ expect.objectContaining({
297
+ query: expect.objectContaining({
298
+ alertId: ALERT_ID,
299
+ alertFeedEventType: AlertFeedEventType.RootCause,
300
+ createdAt: expect.any(FindOperator),
301
+ }),
302
+ }),
303
+ );
304
+ expectCreatedAtCutoff(
305
+ find.mock.calls[0]![0].query.createdAt,
306
+ runCompletedAt,
307
+ );
169
308
  });
170
309
 
171
310
  it("returns null when no analysis has been posted", async () => {
@@ -196,6 +335,43 @@ describe("PostedRootCause.getForSubject", () => {
196
335
  expect(alertFind).not.toHaveBeenCalled();
197
336
  });
198
337
 
338
+ it("forwards the run boundary to the subject-specific reader", async () => {
339
+ const runCompletedAt: Date = new Date("2026-08-07T12:00:00.000Z");
340
+ const getForIncident: jest.SpyInstance = jest
341
+ .spyOn(PostedRootCause, "getForIncident")
342
+ .mockResolvedValue("current analysis");
343
+
344
+ expect(
345
+ await PostedRootCause.getForSubject({
346
+ incidentId: INCIDENT_ID,
347
+ createdAtOrAfter: runCompletedAt,
348
+ }),
349
+ ).toBe("current analysis");
350
+ expect(getForIncident).toHaveBeenCalledWith(INCIDENT_ID, {
351
+ aiRunId: undefined,
352
+ withoutAIRunId: undefined,
353
+ createdAtOrAfter: runCompletedAt,
354
+ });
355
+ });
356
+
357
+ it("forwards the exact run id to the subject-specific reader", async () => {
358
+ const getForAlert: jest.SpyInstance = jest
359
+ .spyOn(PostedRootCause, "getForAlert")
360
+ .mockResolvedValue("current alert analysis");
361
+
362
+ expect(
363
+ await PostedRootCause.getForSubject({
364
+ alertId: ALERT_ID,
365
+ aiRunId: AI_RUN_ID,
366
+ }),
367
+ ).toBe("current alert analysis");
368
+ expect(getForAlert).toHaveBeenCalledWith(ALERT_ID, {
369
+ aiRunId: AI_RUN_ID,
370
+ withoutAIRunId: undefined,
371
+ createdAtOrAfter: undefined,
372
+ });
373
+ });
374
+
199
375
  it("reads the alert feed for an alert subject", async () => {
200
376
  const alertFind: jest.SpyInstance = jest
201
377
  .spyOn(AlertFeedService, "findOneBy")
@@ -252,3 +428,81 @@ describe("PostedRootCause.getForSubject", () => {
252
428
  expect(alertFind).not.toHaveBeenCalled();
253
429
  });
254
430
  });
431
+
432
+ describe("PostedRootCause.getForInvestigation", () => {
433
+ afterEach(() => {
434
+ jest.restoreAllMocks();
435
+ });
436
+
437
+ it("returns the exact run-associated report without a legacy lookup", async () => {
438
+ const getForSubject: jest.SpyInstance = jest
439
+ .spyOn(PostedRootCause, "getForSubject")
440
+ .mockResolvedValue("exact report");
441
+
442
+ expect(
443
+ await PostedRootCause.getForInvestigation({
444
+ incidentId: INCIDENT_ID,
445
+ aiRunId: AI_RUN_ID,
446
+ }),
447
+ ).toBe("exact report");
448
+ expect(getForSubject).toHaveBeenCalledTimes(1);
449
+ expect(getForSubject).toHaveBeenCalledWith({
450
+ incidentId: INCIDENT_ID,
451
+ alertId: undefined,
452
+ aiRunId: AI_RUN_ID,
453
+ });
454
+ });
455
+
456
+ it("recovers a branded null-associated report across a deployment-safe upgrade window", async () => {
457
+ const runCompletedAt: Date = new Date("2026-08-08T10:00:00.000Z");
458
+ const legacyReport: string =
459
+ "## AI — Automated Root Cause Analysis\n\nHistorical evidence.";
460
+ const getForSubject: jest.SpyInstance = jest
461
+ .spyOn(PostedRootCause, "getForSubject")
462
+ .mockResolvedValueOnce(null)
463
+ .mockResolvedValueOnce(legacyReport);
464
+
465
+ expect(
466
+ await PostedRootCause.getForInvestigation({
467
+ alertId: ALERT_ID,
468
+ aiRunId: AI_RUN_ID,
469
+ runCompletedAt,
470
+ }),
471
+ ).toBe(legacyReport);
472
+ expect(getForSubject).toHaveBeenNthCalledWith(2, {
473
+ incidentId: undefined,
474
+ alertId: ALERT_ID,
475
+ withoutAIRunId: true,
476
+ createdAtOrAfter: runCompletedAt,
477
+ });
478
+ });
479
+
480
+ it("rejects ordinary RootCause markdown from the legacy path", async () => {
481
+ jest
482
+ .spyOn(PostedRootCause, "getForSubject")
483
+ .mockResolvedValueOnce(null)
484
+ .mockResolvedValueOnce("## Root cause\n\nWritten by an engineer.");
485
+
486
+ expect(
487
+ await PostedRootCause.getForInvestigation({
488
+ incidentId: INCIDENT_ID,
489
+ aiRunId: AI_RUN_ID,
490
+ runCompletedAt: new Date("2026-08-08T10:00:00.000Z"),
491
+ }),
492
+ ).toBeNull();
493
+ });
494
+
495
+ it("never falls back to an unassociated row without a reliable completion boundary", async () => {
496
+ const getForSubject: jest.SpyInstance = jest
497
+ .spyOn(PostedRootCause, "getForSubject")
498
+ .mockResolvedValue(null);
499
+
500
+ expect(
501
+ await PostedRootCause.getForInvestigation({
502
+ incidentId: INCIDENT_ID,
503
+ aiRunId: AI_RUN_ID,
504
+ }),
505
+ ).toBeNull();
506
+ expect(getForSubject).toHaveBeenCalledTimes(1);
507
+ });
508
+ });
@@ -547,6 +547,8 @@ describe("RemediationExecutionRunner.executeRemediation", () => {
547
547
  );
548
548
  // Persisted budget-ledger string — pinned as a literal on purpose.
549
549
  expect(request.get().feature).toBe("AI Remediation Execution");
550
+ expect(request.get().incidentId).toBe(INCIDENT_ID);
551
+ expect(request.get().alertId).toBeUndefined();
550
552
  });
551
553
 
552
554
  it("runs FullAuto with the execute tool and the allowlist in context when every condition holds", async () => {
@@ -859,6 +861,8 @@ describe("RemediationExecutionRunner.executeRemediation", () => {
859
861
  '<untrusted_context source="alert_text">',
860
862
  );
861
863
  expect(captured!.contextSummary).toContain("Disk almost full on db-1");
864
+ expect(captured!.incidentId).toBeUndefined();
865
+ expect(captured!.alertId).toBe(ALERT_ID);
862
866
  expect(incidentFeed).not.toHaveBeenCalled();
863
867
  expect(alertFeed).toHaveBeenCalledWith(
864
868
  expect.objectContaining({
@@ -260,6 +260,8 @@ describe("RemediationPlanRunner.executePlan", () => {
260
260
  request: expect.objectContaining({
261
261
  // Persisted budget-ledger string — pinned as a literal on purpose.
262
262
  feature: "AI Remediation Planning",
263
+ incidentId: INCIDENT_ID,
264
+ alertId: undefined,
263
265
  }),
264
266
  }),
265
267
  );
@@ -1,4 +1,5 @@
1
1
  import SubjectCodeFixRun from "../../../../Server/Utils/AI/SRE/SubjectCodeFixRun";
2
+ import FixRunBudget from "../../../../Server/Utils/AI/CodeFix/FixRunBudget";
2
3
  import AIRunService from "../../../../Server/Services/AIRunService";
3
4
  import QueryHelper from "../../../../Server/Types/Database/QueryHelper";
4
5
  import AIRun from "../../../../Models/DatabaseModels/AIRun";
@@ -119,6 +120,27 @@ describe("SubjectCodeFixRun dedupe guards", () => {
119
120
  });
120
121
 
121
122
  describe("findNonTerminalRunForSubject", () => {
123
+ test.each([
124
+ { label: "neither", input: {} },
125
+ { label: "both", input: { incidentId, alertId } },
126
+ ])(
127
+ "rejects $label subject type before querying",
128
+ async ({
129
+ input,
130
+ }: {
131
+ input: { incidentId?: ObjectID; alertId?: ObjectID };
132
+ }) => {
133
+ await expect(
134
+ SubjectCodeFixRun.findNonTerminalRunForSubject({
135
+ taskType: CodeFixTaskType.FixFromIncident,
136
+ ...input,
137
+ }),
138
+ ).rejects.toThrow(/Exactly one/);
139
+
140
+ expect(AIRunService.findOneBy).not.toHaveBeenCalled();
141
+ },
142
+ );
143
+
122
144
  test("a NoFixFound run does NOT block a new run for the same subject", async () => {
123
145
  storeRun(AIRunStatus.NoFixFound);
124
146
 
@@ -176,6 +198,28 @@ describe("SubjectCodeFixRun dedupe guards", () => {
176
198
  });
177
199
  });
178
200
 
201
+ describe("enqueueSubjectCodeFixRun", () => {
202
+ test("rejects a dual-subject run before the budget check or write", async () => {
203
+ const assertWithinBudget: jest.SpyInstance = jest.spyOn(
204
+ FixRunBudget,
205
+ "assertWithinBudget",
206
+ );
207
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
208
+
209
+ await expect(
210
+ SubjectCodeFixRun.enqueueSubjectCodeFixRun({
211
+ projectId,
212
+ taskType: CodeFixTaskType.FixFromIncident,
213
+ incidentId,
214
+ alertId,
215
+ }),
216
+ ).rejects.toThrow(/both an incident and an alert/);
217
+
218
+ expect(assertWithinBudget).not.toHaveBeenCalled();
219
+ expect(create).not.toHaveBeenCalled();
220
+ });
221
+ });
222
+
179
223
  describe("findNonTerminalPerformanceFixRunForTrace", () => {
180
224
  test("a NoFixFound run does NOT block a new run for the same trace", async () => {
181
225
  storeRun(AIRunStatus.NoFixFound);
@@ -8,6 +8,7 @@ import {
8
8
  adaptTableSettingsForStorage,
9
9
  applyClusterToMaterializedViewQuery,
10
10
  getClickhouseClusterName,
11
+ getDistributedDdlTaskTimeoutSeconds,
11
12
  getDistributedEngine,
12
13
  getStorageEngine,
13
14
  getStorageTableName,
@@ -33,6 +34,8 @@ import MetricBaselineHourly from "../../../../Models/AnalyticsModels/MetricBasel
33
34
 
34
35
  const CLUSTER_ENV_KEY: string = "CLICKHOUSE_CLUSTER_NAME";
35
36
  const SHARDING_ENV_KEY: string = "CLICKHOUSE_SHARDING_KEY";
37
+ const DDL_TIMEOUT_ENV_KEY: string =
38
+ "CLICKHOUSE_DISTRIBUTED_DDL_TASK_TIMEOUT_SECONDS";
36
39
 
37
40
  /*
38
41
  * Flatten a Statement into a single string (raw SQL + serialized identifier
@@ -49,6 +52,8 @@ function fullText(statement: Statement | string): string {
49
52
  describe("ClickHouse cluster-aware schema (always-on)", () => {
50
53
  const originalCluster: string | undefined = process.env[CLUSTER_ENV_KEY];
51
54
  const originalSharding: string | undefined = process.env[SHARDING_ENV_KEY];
55
+ const originalDdlTimeout: string | undefined =
56
+ process.env[DDL_TIMEOUT_ENV_KEY];
52
57
 
53
58
  afterEach(() => {
54
59
  if (originalCluster === undefined) {
@@ -61,6 +66,11 @@ describe("ClickHouse cluster-aware schema (always-on)", () => {
61
66
  } else {
62
67
  process.env[SHARDING_ENV_KEY] = originalSharding;
63
68
  }
69
+ if (originalDdlTimeout === undefined) {
70
+ delete process.env[DDL_TIMEOUT_ENV_KEY];
71
+ } else {
72
+ process.env[DDL_TIMEOUT_ENV_KEY] = originalDdlTimeout;
73
+ }
64
74
  });
65
75
 
66
76
  describe("ClusterConfig helpers", () => {
@@ -101,6 +111,26 @@ describe("ClickHouse cluster-aware schema (always-on)", () => {
101
111
  );
102
112
  });
103
113
 
114
+ test("distributed DDL task timeout: default 180, overridable, garbage-safe", () => {
115
+ delete process.env[DDL_TIMEOUT_ENV_KEY];
116
+ expect(getDistributedDdlTaskTimeoutSeconds()).toBe(180);
117
+
118
+ process.env[DDL_TIMEOUT_ENV_KEY] = "1800";
119
+ expect(getDistributedDdlTaskTimeoutSeconds()).toBe(1800);
120
+
121
+ // ClickHouse semantics pass through: 0 = async, negative = no server cap.
122
+ process.env[DDL_TIMEOUT_ENV_KEY] = "0";
123
+ expect(getDistributedDdlTaskTimeoutSeconds()).toBe(0);
124
+ process.env[DDL_TIMEOUT_ENV_KEY] = "-1";
125
+ expect(getDistributedDdlTaskTimeoutSeconds()).toBe(-1);
126
+
127
+ // Garbage and whitespace fall back to the default.
128
+ process.env[DDL_TIMEOUT_ENV_KEY] = "not-a-number";
129
+ expect(getDistributedDdlTaskTimeoutSeconds()).toBe(180);
130
+ process.env[DDL_TIMEOUT_ENV_KEY] = " ";
131
+ expect(getDistributedDdlTaskTimeoutSeconds()).toBe(180);
132
+ });
133
+
104
134
  test("distributed engine: model key, with global override winning", () => {
105
135
  delete process.env[SHARDING_ENV_KEY];
106
136
  // model sharding key is used
@@ -24,6 +24,7 @@ import IncludesNone from "../../../../Types/BaseDatabase/IncludesNone";
24
24
  import MultiSearch from "../../../../Types/BaseDatabase/MultiSearch";
25
25
  import Search from "../../../../Types/BaseDatabase/Search";
26
26
  import StartsWith from "../../../../Types/BaseDatabase/StartsWith";
27
+ import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
27
28
  import BadDataException from "../../../../Types/Exception/BadDataException";
28
29
 
29
30
  function expectStatement(actual: Statement, expected: Statement): void {
@@ -1431,6 +1432,125 @@ describe("StatementGenerator", () => {
1431
1432
  });
1432
1433
  });
1433
1434
 
1435
+ /*
1436
+ * The separator here is load-bearing for pagination. `toSortStatement`
1437
+ * used to append sort keys with no delimiter, so anything past the first
1438
+ * key produced a malformed term (`col_1 DESCcol_2 ASC`) — which meant a
1439
+ * multi-key ORDER BY was unusable and, in practice, every paginated read
1440
+ * ran on a single, non-unique sort column. See the pagination-stability
1441
+ * suite in Tests/Server/Services/AnalyticsDatabasePaginationStability.
1442
+ */
1443
+ describe("toSortStatement", () => {
1444
+ /*
1445
+ * TestModel declares its columns through `tableColumns`, not as TS
1446
+ * properties, so a `Sort<TestModel>` literal would fail excess-property
1447
+ * checking on every key. Funnelling through one helper keeps the cast
1448
+ * in a single place instead of on each call.
1449
+ */
1450
+ const sortStatementFor: (sort: Record<string, SortOrder>) => Statement = (
1451
+ sort: Record<string, SortOrder>,
1452
+ ): Statement => {
1453
+ return generator.toSortStatement(sort as any);
1454
+ };
1455
+
1456
+ test("renders a single ascending key with no trailing separator", () => {
1457
+ const statement: Statement = sortStatementFor({
1458
+ column_1: SortOrder.Ascending,
1459
+ });
1460
+
1461
+ expect(statement.query).toBe("{p0:Identifier} ASC");
1462
+ expect(statement.query_params).toStrictEqual({ p0: "column_1" });
1463
+ });
1464
+
1465
+ test("renders a single descending key", () => {
1466
+ const statement: Statement = sortStatementFor({
1467
+ column_1: SortOrder.Descending,
1468
+ });
1469
+
1470
+ expect(statement.query).toBe("{p0:Identifier} DESC");
1471
+ expect(statement.query_params).toStrictEqual({ p0: "column_1" });
1472
+ });
1473
+
1474
+ test("comma separates two keys", () => {
1475
+ const statement: Statement = sortStatementFor({
1476
+ column_1: SortOrder.Descending,
1477
+ column_2: SortOrder.Ascending,
1478
+ });
1479
+
1480
+ expect(statement.query).toBe("{p0:Identifier} DESC, {p1:Identifier} ASC");
1481
+ expect(statement.query_params).toStrictEqual({
1482
+ p0: "column_1",
1483
+ p1: "column_2",
1484
+ });
1485
+ });
1486
+
1487
+ test("comma separates three keys and preserves declaration order", () => {
1488
+ const statement: Statement = sortStatementFor({
1489
+ column_2: SortOrder.Ascending,
1490
+ column_1: SortOrder.Descending,
1491
+ column_ObjectID: SortOrder.Ascending,
1492
+ });
1493
+
1494
+ expect(statement.query).toBe(
1495
+ "{p0:Identifier} ASC, {p1:Identifier} DESC, {p2:Identifier} ASC",
1496
+ );
1497
+ expect(statement.query_params).toStrictEqual({
1498
+ p0: "column_2",
1499
+ p1: "column_1",
1500
+ p2: "column_ObjectID",
1501
+ });
1502
+ });
1503
+
1504
+ /*
1505
+ * Regression guard for the exact malformed shape. Asserting on the
1506
+ * rendered text rather than the param map is deliberate: the old bug
1507
+ * produced correct PARAMS and broken SQL, so a params-only assertion
1508
+ * would have passed straight through it.
1509
+ */
1510
+ test("never concatenates a direction into the next identifier", () => {
1511
+ const statement: Statement = sortStatementFor({
1512
+ column_1: SortOrder.Descending,
1513
+ column_2: SortOrder.Ascending,
1514
+ });
1515
+
1516
+ expect(statement.query).not.toContain("DESC{");
1517
+ expect(statement.query).not.toContain("ASC{");
1518
+ expect(statement.query).toContain(", ");
1519
+ });
1520
+
1521
+ test("separator count is always one fewer than the key count", () => {
1522
+ const statement: Statement = sortStatementFor({
1523
+ column_ObjectID: SortOrder.Ascending,
1524
+ column_1: SortOrder.Ascending,
1525
+ column_2: SortOrder.Ascending,
1526
+ });
1527
+
1528
+ expect(statement.query.split(", ")).toHaveLength(3);
1529
+ });
1530
+
1531
+ test("an empty sort produces an empty statement", () => {
1532
+ const statement: Statement = sortStatementFor({});
1533
+
1534
+ expect(statement.query).toBe("");
1535
+ expect(statement.query_params).toStrictEqual({});
1536
+ });
1537
+
1538
+ test("still rejects an unknown column", () => {
1539
+ expect(() => {
1540
+ return sortStatementFor({ not_a_column: SortOrder.Ascending });
1541
+ }).toThrow(BadDataException);
1542
+ });
1543
+
1544
+ test("rejects an unknown column that appears after a valid one", () => {
1545
+ expect(() => {
1546
+ return sortStatementFor({
1547
+ column_1: SortOrder.Ascending,
1548
+ not_a_column: SortOrder.Descending,
1549
+ });
1550
+ }).toThrow(BadDataException);
1551
+ });
1552
+ });
1553
+
1434
1554
  describe("toColumnsCreateStatement", () => {
1435
1555
  test("should return the columns of a CREATE TABLE statement", () => {
1436
1556
  const statement: Statement = generator.toColumnsCreateStatement([