@oneuptime/common 11.6.1 → 11.6.2

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 (397) hide show
  1. package/Models/AnalyticsModels/Index.ts +4 -0
  2. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  3. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  4. package/Models/AnalyticsModels/SloHistory.ts +240 -0
  5. package/Models/DatabaseModels/Index.ts +20 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  8. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  9. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  10. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  11. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  13. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  14. package/Models/DatabaseModels/ServiceLevelObjective.ts +1106 -0
  15. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  16. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  17. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  24. package/Server/Services/AnalyticsDatabaseService.ts +25 -9
  25. package/Server/Services/Index.ts +24 -0
  26. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  27. package/Server/Services/MetricService.ts +21 -2
  28. package/Server/Services/MonitorService.ts +22 -0
  29. package/Server/Services/NetworkDeviceService.ts +438 -2
  30. package/Server/Services/NetworkEndpointService.ts +414 -0
  31. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  32. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  33. package/Server/Services/NetworkSiteService.ts +1254 -0
  34. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  35. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  36. package/Server/Services/ProjectService.ts +122 -2
  37. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  38. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  39. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  40. package/Server/Services/ServiceLevelObjectiveService.ts +677 -0
  41. package/Server/Services/SloHistoryService.ts +101 -0
  42. package/Server/Services/UserNotificationSettingService.ts +37 -0
  43. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  44. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  45. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  46. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
  47. package/Server/Utils/Memory.ts +9 -1
  48. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  49. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  50. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  51. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  52. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  53. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  54. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  55. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  56. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  57. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  58. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  59. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  60. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  61. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  62. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  63. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  64. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  65. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  66. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  67. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  68. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  69. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  70. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
  72. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  73. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  74. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  75. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  76. package/Tests/Server/Utils/Memory.test.ts +213 -0
  77. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  78. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  79. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  80. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  81. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  82. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  83. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  84. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  85. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  86. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  87. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  88. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  89. package/Tests/Server/Utils/Stream.test.ts +87 -0
  90. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  91. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  92. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  93. package/Tests/Types/Email.test.ts +198 -0
  94. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  95. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  96. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  97. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  98. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  99. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  100. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  101. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  102. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  103. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  104. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  105. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  106. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  107. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  108. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  109. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  110. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  111. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  112. package/Tests/Utils/Base64.test.ts +51 -0
  113. package/Tests/Utils/Boolean.test.ts +76 -0
  114. package/Tests/Utils/Crypto.test.ts +48 -0
  115. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  116. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  117. package/Tests/Utils/Enum.test.ts +54 -0
  118. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  119. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  120. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  121. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  122. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  123. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  124. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  125. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  126. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  127. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  128. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  129. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  130. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  131. package/Tests/Utils/TechStack.test.ts +50 -0
  132. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  133. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  134. package/Types/BaseDatabase/EqualTo.ts +9 -1
  135. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  136. package/Types/BaseDatabase/NotEqual.ts +9 -1
  137. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  138. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  139. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  140. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  141. package/Types/Email/EmailTemplateType.ts +2 -0
  142. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  143. package/Types/Monitor/CriteriaFilter.ts +9 -0
  144. package/Types/Monitor/MonitorStep.ts +5 -8
  145. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  146. package/Types/Monitor/MonitorType.ts +15 -5
  147. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  148. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  149. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  150. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  151. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  152. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  153. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  154. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  155. package/Types/Permission.ts +449 -0
  156. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  157. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  158. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  159. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  160. package/Types/Telemetry/ServiceType.ts +1 -0
  161. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  162. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  163. package/UI/Components/List/List.tsx +8 -0
  164. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  165. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  166. package/UI/Components/Navbar/NavBar.tsx +16 -2
  167. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  168. package/UI/Utils/Navigation.ts +10 -0
  169. package/UI/Utils/TableFilterUrlState.ts +204 -17
  170. package/UI/Utils/TableViewUrlState.ts +165 -0
  171. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  172. package/Utils/Dashboard/Components/Index.ts +7 -0
  173. package/Utils/IpCanonicalUtil.ts +134 -0
  174. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  175. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  176. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  177. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  178. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  179. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  180. package/Utils/Slo/SloStatusColor.ts +54 -0
  181. package/Utils/Slo/SloUtil.ts +637 -0
  182. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  183. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  184. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  185. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  186. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  187. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  188. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  189. package/build/dist/Models/AnalyticsModels/SloHistory.js +215 -0
  190. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  191. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  192. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  193. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  194. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  195. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  196. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  197. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  198. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  199. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  200. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  201. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  202. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  203. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  204. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  205. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  206. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  207. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  208. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  209. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1124 -0
  210. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  211. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  212. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  213. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  214. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  215. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  216. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  229. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
  230. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  231. package/build/dist/Server/Services/Index.js +24 -0
  232. package/build/dist/Server/Services/Index.js.map +1 -1
  233. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  234. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  235. package/build/dist/Server/Services/MetricService.js +21 -3
  236. package/build/dist/Server/Services/MetricService.js.map +1 -1
  237. package/build/dist/Server/Services/MonitorService.js +19 -0
  238. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  239. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  240. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  241. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  242. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  243. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  244. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  245. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  246. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  247. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  248. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  249. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  250. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  251. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  252. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  253. package/build/dist/Server/Services/ProjectService.js +98 -2
  254. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  255. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  256. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  257. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  258. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  259. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  260. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  261. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +582 -0
  262. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  263. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  264. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  265. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  266. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  267. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  268. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  269. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  270. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  271. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  272. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  273. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
  274. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  275. package/build/dist/Server/Utils/Memory.js +9 -1
  276. package/build/dist/Server/Utils/Memory.js.map +1 -1
  277. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  278. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  279. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  280. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  281. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  282. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  283. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  284. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  285. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  286. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  287. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  288. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  289. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  290. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  291. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  292. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  293. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  294. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  295. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  296. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  297. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  298. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  299. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  300. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  301. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  302. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  303. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  304. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  305. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  306. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  307. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  308. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  309. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  310. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  311. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  312. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  313. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  314. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  315. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  316. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  317. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  318. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  319. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  320. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  321. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  322. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  323. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  324. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  325. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  326. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  327. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  328. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  329. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  330. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  331. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  332. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  333. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  334. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  335. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  336. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  337. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  338. package/build/dist/Types/Permission.js +409 -0
  339. package/build/dist/Types/Permission.js.map +1 -1
  340. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  341. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  342. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  343. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  344. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  345. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  346. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  347. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  348. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  349. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  350. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  351. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  352. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  353. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  354. package/build/dist/UI/Components/List/List.js +1 -1
  355. package/build/dist/UI/Components/List/List.js.map +1 -1
  356. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  357. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  358. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  359. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  360. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  361. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  362. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  363. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  364. package/build/dist/UI/Utils/Navigation.js +9 -0
  365. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  366. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  367. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  368. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  369. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  370. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  371. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  372. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  373. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  374. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  375. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  376. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  377. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  378. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  379. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  380. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  381. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  382. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  383. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  384. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  385. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  386. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  387. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  388. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  389. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  390. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  391. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  392. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  393. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  394. package/package.json +2 -2
  395. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  396. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  397. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -0,0 +1,338 @@
1
+ import AnalyticsDatabaseService from "../../../Server/Services/AnalyticsDatabaseService";
2
+ import { Statement } from "../../../Server/Utils/AnalyticsDatabase/Statement";
3
+ import logger from "../../../Server/Utils/Logger";
4
+ import "../TestingUtils/Init";
5
+ import KubernetesCostAllocation from "../../../Models/AnalyticsModels/KubernetesCostAllocation";
6
+ import AggregateBy from "../../../Server/Types/AnalyticsDatabase/AggregateBy";
7
+ import AggregationInterval from "../../../Types/BaseDatabase/AggregationInterval";
8
+ import AggregationType from "../../../Types/BaseDatabase/AggregationType";
9
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
10
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
11
+ import {
12
+ describe,
13
+ expect,
14
+ beforeEach,
15
+ test,
16
+ afterEach,
17
+ jest,
18
+ } from "@jest/globals";
19
+
20
+ /*
21
+ * Statement-generation regressions for the Kubernetes Costs pages.
22
+ *
23
+ * The project- and cluster-level Costs pages issue grouped `Total`
24
+ * (whole-window) aggregations over KubernetesCostAllocation. Under Total
25
+ * the timestamp is selected as `min(windowStart) as windowStart`, and
26
+ * ClickHouse substitutes SELECT aliases into same-level unqualified
27
+ * WHERE references — so the window filter `WHERE windowStart >= ...`
28
+ * compiled to `WHERE min(windowStart) >= ...` and every one of these
29
+ * queries failed with ILLEGAL_AGGREGATION ("Server Error" on the page).
30
+ * The WHERE must therefore be table-qualified; these tests pin the
31
+ * statement shapes the pages depend on.
32
+ */
33
+ describe("KubernetesCostAllocation aggregate statements (Costs pages)", () => {
34
+ const TABLE_NAME: string = "KubernetesCostAllocationV1";
35
+
36
+ const projectId: string = "7b4157fc-c25d-41ea-aabc-972e0ee2c492";
37
+ const startDate: Date = new Date("2026-07-18T10:00:00.000Z");
38
+ const endDate: Date = new Date("2026-07-25T10:00:00.000Z");
39
+
40
+ let service: AnalyticsDatabaseService<KubernetesCostAllocation>;
41
+
42
+ beforeEach(() => {
43
+ service = new AnalyticsDatabaseService({
44
+ modelType: KubernetesCostAllocation,
45
+ });
46
+ jest.spyOn(logger, "debug").mockImplementation(() => {
47
+ return undefined!;
48
+ });
49
+ });
50
+
51
+ afterEach(() => {
52
+ jest.restoreAllMocks();
53
+ });
54
+
55
+ type BuildAggregateByFunction = (
56
+ overrides?: Partial<AggregateBy<KubernetesCostAllocation>>,
57
+ ) => AggregateBy<KubernetesCostAllocation>;
58
+
59
+ /**
60
+ * Mirrors what the Costs pages send (see
61
+ * App/FeatureSet/Dashboard/src/Pages/Kubernetes/Utils/KubernetesCostUtils.ts
62
+ * buildAggregateBy): a project-scoped windowStart range, sorted
63
+ * ascending, LIMIT_PER_PROJECT.
64
+ */
65
+ const buildAggregateBy: BuildAggregateByFunction = (
66
+ overrides?: Partial<AggregateBy<KubernetesCostAllocation>>,
67
+ ): AggregateBy<KubernetesCostAllocation> => {
68
+ return {
69
+ query: {
70
+ projectId: projectId,
71
+ windowStart: new InBetween(startDate, endDate),
72
+ } as AggregateBy<KubernetesCostAllocation>["query"],
73
+ aggregationType: AggregationType.Sum,
74
+ aggregateColumnName: "totalCost",
75
+ aggregationTimestampColumnName: "windowStart",
76
+ startTimestamp: startDate,
77
+ endTimestamp: endDate,
78
+ limit: 10000,
79
+ skip: 0,
80
+ sort: {
81
+ windowStart: SortOrder.Ascending,
82
+ } as AggregateBy<KubernetesCostAllocation>["sort"],
83
+ props: { isRoot: true },
84
+ ...overrides,
85
+ };
86
+ };
87
+
88
+ type BuildResultFunction = (
89
+ aggregateBy: AggregateBy<KubernetesCostAllocation>,
90
+ ) => { query: string; params: Record<string, unknown> };
91
+
92
+ const build: BuildResultFunction = (
93
+ aggregateBy: AggregateBy<KubernetesCostAllocation>,
94
+ ): { query: string; params: Record<string, unknown> } => {
95
+ const result: { statement: Statement; columns: Array<string> } =
96
+ service.toAggregateStatement(aggregateBy);
97
+ return {
98
+ query: result.statement.query,
99
+ params: result.statement.query_params,
100
+ };
101
+ };
102
+
103
+ /**
104
+ * Every WHERE column reference must be qualified with the model table
105
+ * name — an unqualified reference would resolve to the SELECT alias.
106
+ */
107
+ type ExpectQualifiedWhereFunction = (
108
+ query: string,
109
+ params: Record<string, unknown>,
110
+ expectedColumns: Array<string>,
111
+ ) => void;
112
+
113
+ const expectQualifiedWhere: ExpectQualifiedWhereFunction = (
114
+ query: string,
115
+ params: Record<string, unknown>,
116
+ expectedColumns: Array<string>,
117
+ ): void => {
118
+ const qualifierTables: Array<unknown> = Object.entries(params)
119
+ .filter(([key]: [string, unknown]) => {
120
+ return key.endsWith("_t");
121
+ })
122
+ .map(([, value]: [string, unknown]) => {
123
+ return value;
124
+ });
125
+ const qualifierColumns: Array<unknown> = Object.entries(params)
126
+ .filter(([key]: [string, unknown]) => {
127
+ return key.endsWith("_c");
128
+ })
129
+ .map(([, value]: [string, unknown]) => {
130
+ return value;
131
+ });
132
+
133
+ expect(qualifierTables).toHaveLength(expectedColumns.length);
134
+ for (const table of qualifierTables) {
135
+ expect(table).toBe(TABLE_NAME);
136
+ }
137
+ expect([...qualifierColumns].sort()).toStrictEqual(
138
+ [...expectedColumns].sort(),
139
+ );
140
+ // The WHERE must not contain a single bare identifier reference.
141
+ expect(query).not.toMatch(/AND \{p\d+:Identifier\}/);
142
+ };
143
+
144
+ test("spend-by-cluster (grouped Total) keeps min(windowStart) and a qualified window filter", () => {
145
+ // fetchClusterBreakdown: sum(totalCost) grouped by clusterName, Total.
146
+ const { query, params } = build(
147
+ buildAggregateBy({
148
+ groupBy: {
149
+ clusterName: true,
150
+ } as AggregateBy<KubernetesCostAllocation>["groupBy"],
151
+ aggregationInterval: AggregationInterval.Total,
152
+ }),
153
+ );
154
+
155
+ expect(query).toContain("sum(totalCost) as totalCost");
156
+ expect(query).toContain("min(windowStart) as windowStart");
157
+ expect(query).not.toContain("date_trunc");
158
+
159
+ expectQualifiedWhere(query, params, [
160
+ "projectId",
161
+ "windowStart",
162
+ "windowStart",
163
+ ]);
164
+
165
+ // Grouped by the cluster column only — never by the Total timestamp.
166
+ expect(query).toContain("GROUP BY {p9:Identifier}");
167
+ expect(params["p9"]).toBe("clusterName");
168
+ // Grouped queries never carry the empty-window phantom-row guard.
169
+ expect(query).not.toContain("HAVING count() > 0");
170
+
171
+ /*
172
+ * ORDER BY / GROUP BY must stay UNqualified: they are meant to
173
+ * resolve to the SELECT aliases (a qualified ORDER BY would hit
174
+ * NOT_AN_AGGREGATE under GROUP BY).
175
+ */
176
+ expect(query).toMatch(/ORDER BY \{p\d+:Identifier\} ASC/);
177
+
178
+ expect(Object.values(params)).toContain(TABLE_NAME);
179
+ expect(Object.values(params)).toContain(projectId);
180
+ });
181
+
182
+ test("idle-spend variant adds a qualified namespace filter", () => {
183
+ // fetchClusterBreakdown's idle query: extraQuery namespace="__idle__".
184
+ const { query, params } = build(
185
+ buildAggregateBy({
186
+ query: {
187
+ projectId: projectId,
188
+ windowStart: new InBetween(startDate, endDate),
189
+ namespace: "__idle__",
190
+ } as AggregateBy<KubernetesCostAllocation>["query"],
191
+ groupBy: {
192
+ clusterName: true,
193
+ } as AggregateBy<KubernetesCostAllocation>["groupBy"],
194
+ aggregationInterval: AggregationInterval.Total,
195
+ }),
196
+ );
197
+
198
+ expect(query).toContain("min(windowStart) as windowStart");
199
+ expectQualifiedWhere(query, params, [
200
+ "projectId",
201
+ "windowStart",
202
+ "windowStart",
203
+ "namespace",
204
+ ]);
205
+ expect(Object.values(params)).toContain("__idle__");
206
+ });
207
+
208
+ test("efficiency variant (Avg over totalEfficiency) is qualified the same way", () => {
209
+ const { query, params } = build(
210
+ buildAggregateBy({
211
+ aggregateColumnName: "totalEfficiency",
212
+ aggregationType: AggregationType.Avg,
213
+ groupBy: {
214
+ clusterName: true,
215
+ } as AggregateBy<KubernetesCostAllocation>["groupBy"],
216
+ aggregationInterval: AggregationInterval.Total,
217
+ }),
218
+ );
219
+
220
+ expect(query).toContain("avg(totalEfficiency) as totalEfficiency");
221
+ expect(query).toContain("min(windowStart) as windowStart");
222
+ expectQualifiedWhere(query, params, [
223
+ "projectId",
224
+ "windowStart",
225
+ "windowStart",
226
+ ]);
227
+ });
228
+
229
+ test("namespace/workload breakdowns group by multiple columns under Total", () => {
230
+ // fetchWorkloadBreakdown groups by namespace + controllerKind + controllerName.
231
+ const { query, params } = build(
232
+ buildAggregateBy({
233
+ groupBy: {
234
+ namespace: true,
235
+ controllerKind: true,
236
+ controllerName: true,
237
+ } as AggregateBy<KubernetesCostAllocation>["groupBy"],
238
+ aggregationInterval: AggregationInterval.Total,
239
+ }),
240
+ );
241
+
242
+ expect(query).toContain("min(windowStart) as windowStart");
243
+ expectQualifiedWhere(query, params, [
244
+ "projectId",
245
+ "windowStart",
246
+ "windowStart",
247
+ ]);
248
+ const paramValues: Array<unknown> = Object.values(params);
249
+ expect(paramValues).toContain("namespace");
250
+ expect(paramValues).toContain("controllerKind");
251
+ expect(paramValues).toContain("controllerName");
252
+ });
253
+
254
+ test("cost-trend (bucketed) query is qualified and groups by the bucket alias", () => {
255
+ // fetchCostTrend: no groupBy, interval derived from the 7-day window.
256
+ const { query, params } = build(buildAggregateBy());
257
+
258
+ // A 7-day window derives an Hour bucket.
259
+ expect(query).toContain(
260
+ "date_trunc('hour', toStartOfInterval(windowStart, INTERVAL 1 hour)) as windowStart",
261
+ );
262
+ expect(query).not.toContain("min(windowStart)");
263
+
264
+ /*
265
+ * The window filter must read the RAW windowStart column. Before
266
+ * qualification the bucket alias was substituted into WHERE, which
267
+ * silently snapped the window edges to bucket boundaries.
268
+ */
269
+ expectQualifiedWhere(query, params, [
270
+ "projectId",
271
+ "windowStart",
272
+ "windowStart",
273
+ ]);
274
+
275
+ // The GROUP BY targets the bucket alias — bare, never qualified.
276
+ expect(query).toContain("GROUP BY windowStart");
277
+ expect(query).toMatch(/ORDER BY \{p\d+:Identifier\} ASC/);
278
+ });
279
+
280
+ test("cluster-scoped queries (cluster view page) qualify the kubernetesClusterId filter", () => {
281
+ const clusterId: string = "0a1b2c3d-0000-0000-0000-000000000000";
282
+ const { query, params } = build(
283
+ buildAggregateBy({
284
+ query: {
285
+ projectId: projectId,
286
+ windowStart: new InBetween(startDate, endDate),
287
+ kubernetesClusterId: clusterId,
288
+ } as AggregateBy<KubernetesCostAllocation>["query"],
289
+ groupBy: {
290
+ namespace: true,
291
+ } as AggregateBy<KubernetesCostAllocation>["groupBy"],
292
+ aggregationInterval: AggregationInterval.Total,
293
+ }),
294
+ );
295
+
296
+ expectQualifiedWhere(query, params, [
297
+ "projectId",
298
+ "windowStart",
299
+ "windowStart",
300
+ "kubernetesClusterId",
301
+ ]);
302
+ expect(Object.values(params)).toContain(clusterId);
303
+ });
304
+
305
+ test("group-less Total keeps the qualified filter and the empty-window guard", () => {
306
+ const { query, params } = build(
307
+ buildAggregateBy({
308
+ aggregationInterval: AggregationInterval.Total,
309
+ }),
310
+ );
311
+
312
+ expect(query).toContain("min(windowStart) as windowStart");
313
+ expect(query).not.toContain("GROUP BY");
314
+ expect(query).toContain("HAVING count() > 0");
315
+ expectQualifiedWhere(query, params, [
316
+ "projectId",
317
+ "windowStart",
318
+ "windowStart",
319
+ ]);
320
+ });
321
+
322
+ test("the retention read filter stays a raw unaliased predicate", () => {
323
+ /*
324
+ * `retentionDate >= now()` is appended as raw SQL. No SELECT alias
325
+ * named retentionDate exists, so it needs no qualification — but it
326
+ * must be present on every aggregate read.
327
+ */
328
+ const { query } = build(
329
+ buildAggregateBy({
330
+ groupBy: {
331
+ clusterName: true,
332
+ } as AggregateBy<KubernetesCostAllocation>["groupBy"],
333
+ aggregationInterval: AggregationInterval.Total,
334
+ }),
335
+ );
336
+ expect(query).toContain("retentionDate >= now()");
337
+ });
338
+ });
@@ -371,6 +371,148 @@ describe("MetricService aggregate statement generation", () => {
371
371
  });
372
372
  });
373
373
 
374
+ /*
375
+ * WHERE table qualification. The scalar and mutable builders alias
376
+ * aggregates to real column names (`<agg> as value`, `min(time) as
377
+ * time` under Total) at the same level as their WHERE clause, and
378
+ * ClickHouse substitutes SELECT aliases into same-level unqualified
379
+ * WHERE references — a Total metric aggregation therefore compiled to
380
+ * `WHERE min(time) >= ...` (ILLEGAL_AGGREGATION). The WHERE must
381
+ * reference `MetricItemV3.time` / the dedup-subquery alias instead.
382
+ */
383
+ describe("WHERE table qualification", () => {
384
+ type QualifierValues = (result: {
385
+ statement: Statement;
386
+ columns: Array<string>;
387
+ }) => Array<unknown>;
388
+ const qualifierValues: QualifierValues = (result: {
389
+ statement: Statement;
390
+ columns: Array<string>;
391
+ }): Array<unknown> => {
392
+ return Object.entries(result.statement.query_params)
393
+ .filter(([key]: [string, unknown]) => {
394
+ return key.endsWith("_t");
395
+ })
396
+ .map(([, value]: [string, unknown]) => {
397
+ return value;
398
+ });
399
+ };
400
+
401
+ it("qualifies the base scalar path with the Metric table name", () => {
402
+ // An attribute filter blocks the MVs and routes to the base table.
403
+ const result: { statement: Statement; columns: Array<string> } =
404
+ service.toAggregateStatement(
405
+ buildAggregateBy({
406
+ query: {
407
+ projectId: projectId,
408
+ name: "http.client.request.duration",
409
+ time: new InBetween(startDate, endDate),
410
+ attributes: { "oneuptime.service.name": "starship-web" },
411
+ } as unknown as AggregateBy<Metric>["query"],
412
+ }),
413
+ );
414
+ const query: string = result.statement.query;
415
+
416
+ expect(query).toMatch(
417
+ /\{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} >= \{p\d+:DateTime64\(9\)\}/,
418
+ );
419
+ const qualifiers: Array<unknown> = qualifierValues(result);
420
+ expect(qualifiers.length).toBeGreaterThan(0);
421
+ for (const qualifier of qualifiers) {
422
+ expect(qualifier).toBe("MetricItemV3");
423
+ }
424
+ });
425
+
426
+ it("keeps min(time) valid on the direct (non-subquery) scalar form under Total", () => {
427
+ /*
428
+ * Distribution hint + no attribute grouping = the SELECT aliases
429
+ * and the WHERE share one query level — the exact shape that
430
+ * failed with ILLEGAL_AGGREGATION before qualification.
431
+ */
432
+ const aggregateBy: AggregateBy<Metric> = buildAggregateBy({
433
+ aggregationInterval: AggregationInterval.Total,
434
+ query: {
435
+ projectId: projectId,
436
+ name: "http.client.request.duration",
437
+ time: new InBetween(startDate, endDate),
438
+ attributes: { "oneuptime.service.name": "starship-web" },
439
+ } as unknown as AggregateBy<Metric>["query"],
440
+ });
441
+
442
+ const result: { statement: Statement; columns: Array<string> } =
443
+ service.toAggregateStatement(aggregateBy);
444
+ const query: string = result.statement.query;
445
+
446
+ expect(query).toContain("min(time) as time");
447
+ expect(query).toMatch(
448
+ /\{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} >= \{p\d+:DateTime64\(9\)\}/,
449
+ );
450
+ for (const qualifier of qualifierValues(result)) {
451
+ expect(qualifier).toBe("MetricItemV3");
452
+ }
453
+ });
454
+
455
+ it("leaves the minute-MV fast path unqualified (different table, no alias capture)", () => {
456
+ /*
457
+ * The MV statement filters on bucketTime/projectId/name against
458
+ * MetricItemAggMV1m — qualifying with the base table name would
459
+ * be invalid there, and its SELECT aliases shadow no MV column.
460
+ */
461
+ const result: { statement: Statement; columns: Array<string> } =
462
+ service.toAggregateStatement(buildAggregateBy());
463
+
464
+ expect(result.statement.query).toContain("MetricItemAggMV1m");
465
+ expect(qualifierValues(result)).toHaveLength(0);
466
+ });
467
+
468
+ it("qualifies the mutable-metric outer WHERE with the dedup subquery alias", () => {
469
+ const result: { statement: Statement; columns: Array<string> } =
470
+ service.toAggregateStatement(
471
+ buildAggregateBy({
472
+ query: {
473
+ projectId: projectId,
474
+ name: "oneuptime.incident.count",
475
+ time: new InBetween(startDate, endDate),
476
+ } as AggregateBy<Metric>["query"],
477
+ }),
478
+ );
479
+ const query: string = result.statement.query;
480
+
481
+ // The argMax dedup subquery must carry the alias the WHERE uses.
482
+ expect(query).toContain(") AS mutable_metric_latest");
483
+ expect(query).toMatch(
484
+ /\{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} >= \{p\d+:DateTime64\(9\)\}/,
485
+ );
486
+ for (const qualifier of qualifierValues(result)) {
487
+ expect(qualifier).toBe("mutable_metric_latest");
488
+ }
489
+ });
490
+
491
+ it("keeps min(time) valid on the mutable path under Total", () => {
492
+ const result: { statement: Statement; columns: Array<string> } =
493
+ service.toAggregateStatement(
494
+ buildAggregateBy({
495
+ aggregationInterval: AggregationInterval.Total,
496
+ query: {
497
+ projectId: projectId,
498
+ name: "oneuptime.incident.count",
499
+ time: new InBetween(startDate, endDate),
500
+ } as AggregateBy<Metric>["query"],
501
+ }),
502
+ );
503
+ const query: string = result.statement.query;
504
+
505
+ expect(query).toContain("min(time) as time");
506
+ expect(query).toContain(") AS mutable_metric_latest");
507
+ // Group-less Total: no time grouping, phantom row suppressed.
508
+ expect(query).not.toContain("GROUP BY time");
509
+ expect(query).toContain("HAVING count() > 0");
510
+ for (const qualifier of qualifierValues(result)) {
511
+ expect(qualifier).toBe("mutable_metric_latest");
512
+ }
513
+ });
514
+ });
515
+
374
516
  /*
375
517
  * The sub-hour tiers (FiveMinutes/FifteenMinutes/ThirtyMinutes) are NOT
376
518
  * valid ClickHouse date_trunc units — they must compile through the