@oneuptime/common 12.0.15 → 12.0.16

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 (707) hide show
  1. package/Models/AnalyticsModels/Index.ts +10 -0
  2. package/Models/AnalyticsModels/LogCountBaseline.ts +174 -0
  3. package/Models/AnalyticsModels/SecurityEvent.ts +794 -0
  4. package/Models/AnalyticsModels/Span.ts +29 -1
  5. package/Models/AnalyticsModels/SpanCountBaseline.ts +198 -0
  6. package/Models/DatabaseModels/Alert.ts +42 -0
  7. package/Models/DatabaseModels/AlertMeasurement.ts +1114 -0
  8. package/Models/DatabaseModels/AlertMeasurementValue.ts +501 -0
  9. package/Models/DatabaseModels/AlertStateTimeline.ts +10 -2
  10. package/Models/DatabaseModels/BillingPaymentMethod.ts +8 -10
  11. package/Models/DatabaseModels/DetectionRule.ts +487 -0
  12. package/Models/DatabaseModels/GoogleSecOpsConnection.ts +382 -0
  13. package/Models/DatabaseModels/Incident.ts +42 -0
  14. package/Models/DatabaseModels/IncidentMeasurement.ts +1114 -0
  15. package/Models/DatabaseModels/IncidentMeasurementValue.ts +501 -0
  16. package/Models/DatabaseModels/IncidentStateTimeline.ts +10 -2
  17. package/Models/DatabaseModels/IncomingCallPolicyLabelRule.ts +36 -0
  18. package/Models/DatabaseModels/IncomingCallPolicyOwnerRule.ts +42 -0
  19. package/Models/DatabaseModels/Index.ts +20 -0
  20. package/Models/DatabaseModels/Label.ts +11 -0
  21. package/Models/DatabaseModels/LlmCostBudget.ts +655 -0
  22. package/Models/DatabaseModels/LlmModelPrice.ts +481 -0
  23. package/Models/DatabaseModels/LogSavedView.ts +87 -0
  24. package/Models/DatabaseModels/MarketingConversion.ts +210 -8
  25. package/Models/DatabaseModels/MetricSavedView.ts +59 -0
  26. package/Models/DatabaseModels/OnCallDutyPolicyLabelRule.ts +36 -0
  27. package/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.ts +42 -0
  28. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.ts +36 -0
  29. package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.ts +42 -0
  30. package/Models/DatabaseModels/Probe.ts +21 -0
  31. package/Models/DatabaseModels/RunbookLabelRule.ts +36 -0
  32. package/Models/DatabaseModels/RunbookOwnerRule.ts +42 -0
  33. package/Models/DatabaseModels/ScheduledMaintenanceMeasurement.ts +1104 -0
  34. package/Models/DatabaseModels/ScheduledMaintenanceMeasurementValue.ts +491 -0
  35. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +10 -2
  36. package/Models/DatabaseModels/StatusPageLabelRule.ts +36 -0
  37. package/Models/DatabaseModels/StatusPageOwnerRule.ts +42 -0
  38. package/Models/DatabaseModels/TableView.ts +15 -0
  39. package/Models/DatabaseModels/Team.ts +13 -0
  40. package/Models/DatabaseModels/TeamMember.ts +8 -0
  41. package/Models/DatabaseModels/TraceSavedView.ts +52 -0
  42. package/Models/DatabaseModels/WorkflowLabelRule.ts +36 -0
  43. package/Models/DatabaseModels/WorkflowOwnerRule.ts +42 -0
  44. package/Server/API/TelemetryAPI.ts +252 -6
  45. package/Server/API/UserAPI.ts +88 -0
  46. package/Server/EnvironmentConfig.ts +36 -1
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1788000000000-AddDetectionRuleAndGoogleSecOpsConnection.ts +88 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1788100000000-AddMeasurements.ts +457 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1788200000000-AddLlmCostBudget.ts +97 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1788300000000-AddLlmModelPrice.ts +45 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/1788400000000-AddMarketingConversionAttribution.ts +105 -0
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/1788500000000-RemoveLlmCostBudgetAlertColumns.ts +77 -0
  53. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  54. package/Server/Middleware/IdentityRateLimit.ts +672 -0
  55. package/Server/Services/AccessTokenService.ts +15 -2
  56. package/Server/Services/AlertMeasurementService.ts +302 -0
  57. package/Server/Services/AlertMeasurementValueService.ts +508 -0
  58. package/Server/Services/AlertService.ts +50 -0
  59. package/Server/Services/AlertStateTimelineService.ts +54 -0
  60. package/Server/Services/DetectionRuleService.ts +74 -0
  61. package/Server/Services/GoogleSecOpsConnectionService.ts +89 -0
  62. package/Server/Services/IncidentMeasurementService.ts +304 -0
  63. package/Server/Services/IncidentMeasurementValueService.ts +523 -0
  64. package/Server/Services/IncidentService.ts +51 -0
  65. package/Server/Services/IncidentStateTimelineService.ts +54 -0
  66. package/Server/Services/Index.ts +30 -0
  67. package/Server/Services/LlmCostBudgetService.ts +93 -0
  68. package/Server/Services/LlmModelPriceService.ts +202 -0
  69. package/Server/Services/LogAggregationService.ts +1106 -2
  70. package/Server/Services/LogCountBaselineService.ts +163 -0
  71. package/Server/Services/MutableMetricService.ts +30 -9
  72. package/Server/Services/ScheduledMaintenanceMeasurementService.ts +311 -0
  73. package/Server/Services/ScheduledMaintenanceMeasurementValueService.ts +546 -0
  74. package/Server/Services/ScheduledMaintenanceService.ts +53 -0
  75. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +188 -1
  76. package/Server/Services/SecurityEventService.ts +104 -0
  77. package/Server/Services/SpanCountBaselineService.ts +173 -0
  78. package/Server/Services/StatusPageService.ts +4 -3
  79. package/Server/Services/TelemetryUsageBillingService.ts +17 -2
  80. package/Server/Services/UserService.ts +284 -51
  81. package/Server/Services/UserTotpAuthService.ts +27 -86
  82. package/Server/Services/UserWebAuthnService.ts +26 -86
  83. package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +14 -0
  84. package/Server/Types/Database/Permissions/TenantPermission.ts +10 -0
  85. package/Server/Types/Database/QueryHelper.ts +1 -1
  86. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  87. package/Server/Utils/AI/Toolbox/Index.ts +6 -0
  88. package/Server/Utils/AI/Toolbox/SecurityEventTools.ts +349 -0
  89. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -4
  90. package/Server/Utils/Attribution.ts +130 -34
  91. package/Server/Utils/Marketing/ConversionUploadProvider.ts +98 -16
  92. package/Server/Utils/Marketing/Providers/GoogleAds.ts +70 -7
  93. package/Server/Utils/Marketing/Providers/LinkedIn.ts +54 -16
  94. package/Server/Utils/Marketing/Providers/Meta.ts +52 -18
  95. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +37 -10
  96. package/Server/Utils/Marketing/Providers/Reddit.ts +45 -15
  97. package/Server/Utils/Measurement/MeasurementDefinitionValidator.ts +209 -0
  98. package/Server/Utils/Measurement/MeasurementMetricWriter.ts +189 -0
  99. package/Server/Utils/Monitor/Criteria/CountAnomaly.ts +182 -0
  100. package/Server/Utils/Monitor/Criteria/LogMonitorCriteria.ts +132 -0
  101. package/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.ts +35 -0
  102. package/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.ts +132 -0
  103. package/Server/Utils/Monitor/DataToProcess.ts +2 -0
  104. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  105. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +15 -0
  106. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +20 -0
  107. package/Server/Utils/Monitor/MonitorResource.ts +16 -0
  108. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +1 -0
  109. package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +1 -0
  110. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +548 -0
  111. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +262 -0
  112. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +212 -0
  113. package/Server/Utils/SecurityEvent/SecurityEventRow.ts +101 -0
  114. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +635 -0
  115. package/Server/Utils/Telemetry/LlmCostBudgetEvaluator.ts +379 -0
  116. package/Server/Utils/Telemetry/LlmSpan.ts +83 -4
  117. package/Server/Utils/Telemetry/LogErrorPatternSql.ts +136 -0
  118. package/Server/Utils/UserPermission/UserPermission.ts +57 -1
  119. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +4 -0
  120. package/Tests/App/Dashboard/CreatePageEntryPointPermissions.test.tsx +306 -0
  121. package/Tests/App/Dashboard/DangerZone.test.tsx +11 -0
  122. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +4 -0
  123. package/Tests/App/Dashboard/LogMonitorAttributeOperatorPreview.test.tsx +459 -0
  124. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +24 -0
  125. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +6 -0
  126. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +323 -0
  127. package/Tests/Models/DatabaseModels/ProjectSharedResources.test.ts +386 -0
  128. package/Tests/Server/API/LogErrorPatternAPI.test.ts +811 -0
  129. package/Tests/Server/API/UserAuthenticationAPI.test.ts +11 -0
  130. package/Tests/Server/API/UserProjectsAPI.test.ts +11 -2
  131. package/Tests/Server/API/UserTwoFactorAuthAdminAPI.test.ts +918 -0
  132. package/Tests/Server/Infrastructure/LocalCache.test.ts +149 -0
  133. package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +249 -0
  134. package/Tests/Server/Services/AlertMeasurementService.test.ts +665 -0
  135. package/Tests/Server/Services/AlertMeasurementValueService.test.ts +389 -0
  136. package/Tests/Server/Services/DetectionRuleService.test.ts +254 -0
  137. package/Tests/Server/Services/IncidentMeasurementService.test.ts +394 -0
  138. package/Tests/Server/Services/IncidentMeasurementValueService.test.ts +816 -0
  139. package/Tests/Server/Services/LlmCostBudgetService.test.ts +104 -0
  140. package/Tests/Server/Services/LogAggregationAttributeOperators.test.ts +405 -0
  141. package/Tests/Server/Services/LogErrorPatternAggregation.test.ts +804 -0
  142. package/Tests/Server/Services/MutableMetricNameRouting.test.ts +83 -0
  143. package/Tests/Server/Services/ScheduledMaintenanceMeasurementService.test.ts +750 -0
  144. package/Tests/Server/Services/ScheduledMaintenanceMeasurementValueService.test.ts +478 -0
  145. package/Tests/Server/Services/UserAuthenticationService.test.ts +216 -4
  146. package/Tests/Server/Services/UserTwoFactorAuthAdmin.test.ts +1190 -0
  147. package/Tests/Server/Types/Database/Permissions/ScopedRoleSharedResourceAccess.test.ts +466 -0
  148. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +265 -0
  149. package/Tests/Server/Types/Database/QueryHelperTextAndStructuralOperators.test.ts +206 -0
  150. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +6 -0
  151. package/Tests/Server/Utils/AnalyticsDatabase/FractionalAttributeThreshold.test.ts +224 -0
  152. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +172 -2
  153. package/Tests/Server/Utils/Attribution.test.ts +228 -1
  154. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +153 -92
  155. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +123 -6
  156. package/Tests/Server/Utils/Marketing/GoogleAds.test.ts +253 -1
  157. package/Tests/Server/Utils/Marketing/LinkedIn.test.ts +282 -0
  158. package/Tests/Server/Utils/Marketing/Meta.test.ts +304 -0
  159. package/Tests/Server/Utils/Marketing/MicrosoftAds.test.ts +263 -0
  160. package/Tests/Server/Utils/Marketing/Reddit.test.ts +259 -0
  161. package/Tests/Server/Utils/Measurement/MeasurementDefinitionValidator.test.ts +322 -0
  162. package/Tests/Server/Utils/Measurement/MeasurementMetricWriter.test.ts +373 -0
  163. package/Tests/Server/Utils/Monitor/Criteria/CountAnomaly.test.ts +221 -0
  164. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +236 -0
  165. package/Tests/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.test.ts +147 -0
  166. package/Tests/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.test.ts +274 -0
  167. package/Tests/Server/Utils/Monitor/SecurityEventsMonitorDataExtractor.test.ts +93 -0
  168. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +660 -0
  169. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +308 -0
  170. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +271 -0
  171. package/Tests/Server/Utils/SecurityEvent/SecurityEventRow.test.ts +272 -0
  172. package/Tests/Server/Utils/SecurityEvent/SigmaClickhouseCompiler.test.ts +511 -0
  173. package/Tests/Server/Utils/Telemetry/LlmCostBudgetEvaluator.test.ts +497 -0
  174. package/Tests/Server/Utils/Telemetry/LlmSpan.test.ts +380 -0
  175. package/Tests/Server/Utils/Telemetry/LogErrorPatternSql.test.ts +207 -0
  176. package/Tests/Server/Utils/UserPermission/ProjectUserGrant.test.ts +293 -0
  177. package/Tests/Types/Monitor/MonitorStepInfraMonitorUtils.test.ts +194 -0
  178. package/Tests/Types/Monitor/MonitorStepSecurityEventsMonitor.test.ts +201 -0
  179. package/Tests/Types/SecurityEvent/OcsfEventClass.test.ts +105 -0
  180. package/Tests/Types/SecurityEvent/OcsfSeverity.test.ts +111 -0
  181. package/Tests/Types/Telemetry/LlmCostCatalog.test.ts +516 -0
  182. package/Tests/UI/Components/ActiveFilterChipsOperatorValues.test.tsx +222 -0
  183. package/Tests/UI/Components/BulkActionPermissionGating.test.tsx +296 -0
  184. package/Tests/UI/Components/CardModelDetailPermissionGating.test.tsx +305 -0
  185. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +23 -0
  186. package/Tests/UI/Components/DictionaryFilterOperatorDisplay.test.ts +239 -0
  187. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +267 -0
  188. package/Tests/UI/Components/DuplicateModel.test.tsx +37 -0
  189. package/Tests/UI/Components/ModelCardPermissionGating.test.tsx +348 -0
  190. package/Tests/UI/Components/ModelDelete.test.tsx +25 -1
  191. package/Tests/UI/Components/ModelFormCreatePermission.test.tsx +342 -0
  192. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +680 -0
  193. package/Tests/UI/Components/OrderedStatesListCreateGate.test.tsx +174 -0
  194. package/Tests/UI/Components/SavedViewsDropdownSearch.test.tsx +1127 -0
  195. package/Tests/UI/Components/SavedViewsFacetSection.test.tsx +958 -0
  196. package/Tests/UI/Components/SavedViewsList.test.ts +699 -0
  197. package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +640 -0
  198. package/Tests/UI/Components/SavedViewsSurfaceParity.test.tsx +679 -0
  199. package/Tests/UI/Components/TableViewLoadFailure.test.tsx +248 -0
  200. package/Tests/UI/Types/UseComponentOutsideClick.test.tsx +226 -0
  201. package/Tests/UI/Utils/PermissionGate.test.ts +467 -0
  202. package/Tests/Utils/Measurement/MeasurementEvaluator.test.ts +639 -0
  203. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  204. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +285 -0
  205. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +433 -0
  206. package/Tests/Utils/SecurityEvent/GenericNormalizer.test.ts +204 -0
  207. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +252 -0
  208. package/Tests/Utils/SecurityEvent/NormalizerHelpers.test.ts +274 -0
  209. package/Tests/Utils/SecurityEvent/OcsfNormalizer.test.ts +208 -0
  210. package/Tests/Utils/SecurityEvent/SecurityEventNormalizer.test.ts +172 -0
  211. package/Tests/Utils/SecurityEvent/SigmaRuleParser.test.ts +471 -0
  212. package/Tests/Utils/SecurityEvent/UdmNormalizer.test.ts +361 -0
  213. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +82 -0
  214. package/Tests/Utils/Telemetry/LogErrorPattern.test.ts +463 -0
  215. package/Types/AI/AIChatTypes.ts +1 -0
  216. package/Types/Alerts/AlertMeasurementAnchorType.ts +14 -0
  217. package/Types/Alerts/AlertStateRole.ts +11 -0
  218. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +16 -0
  219. package/Types/Dashboard/Chart/ChartType.ts +1 -0
  220. package/Types/Dashboard/DashboardComponentType.ts +2 -0
  221. package/Types/Dashboard/DashboardComponents/DashboardSecurityEventsFlowComponent.ts +18 -0
  222. package/Types/Dashboard/DashboardComponents/DashboardSecurityEventsListComponent.ts +16 -0
  223. package/Types/Incident/IncidentMeasurementAnchorType.ts +34 -0
  224. package/Types/Incident/IncidentStateRole.ts +14 -0
  225. package/Types/Marketing/Attribution.ts +75 -0
  226. package/Types/Marketing/MarketingConversion.ts +37 -7
  227. package/Types/Measurement/MeasurementAggregationType.ts +43 -0
  228. package/Types/Measurement/MeasurementAnchorKind.ts +23 -0
  229. package/Types/Measurement/MeasurementOccurrence.ts +14 -0
  230. package/Types/Measurement/MeasurementStatus.ts +34 -0
  231. package/Types/MeteredPlan/ProductType.ts +1 -0
  232. package/Types/Monitor/CriteriaFilter.ts +3 -0
  233. package/Types/Monitor/MonitorCriteriaInstance.ts +64 -0
  234. package/Types/Monitor/MonitorStep.ts +28 -0
  235. package/Types/Monitor/MonitorStepSecurityEventsMonitor.ts +100 -0
  236. package/Types/Monitor/MonitorType.ts +20 -0
  237. package/Types/Monitor/SecurityEventsMonitor/SecurityEventsMonitorResponse.ts +17 -0
  238. package/Types/Permission.ts +399 -2
  239. package/Types/ScheduledMaintenance/ScheduledMaintenanceMeasurementAnchorType.ts +20 -0
  240. package/Types/ScheduledMaintenance/ScheduledMaintenanceStateRole.ts +16 -0
  241. package/Types/SecurityEvent/NormalizedSecurityEvent.ts +92 -0
  242. package/Types/SecurityEvent/OcsfEventClass.ts +205 -0
  243. package/Types/SecurityEvent/OcsfSeverity.ts +88 -0
  244. package/Types/SecurityEvent/SecurityEventFormat.ts +23 -0
  245. package/Types/SecurityEvent/SigmaRule.ts +70 -0
  246. package/Types/Telemetry/LlmConventions.ts +20 -1
  247. package/Types/Telemetry/LlmCostCatalog.ts +557 -0
  248. package/Types/Telemetry/ServiceType.ts +1 -0
  249. package/Types/Telemetry/TelemetryRetentionConfig.ts +5 -1
  250. package/Types/Telemetry/TelemetryType.ts +1 -0
  251. package/Types/TwoFactorAuthStatus.ts +42 -0
  252. package/Types/UserAuthenticationStatus.ts +18 -0
  253. package/UI/Components/ActionButton/ActionButtonSchema.ts +7 -0
  254. package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +35 -2
  255. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +34 -1
  256. package/UI/Components/BulkUpdate/BulkOwnerActions.tsx +45 -1
  257. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +3 -0
  258. package/UI/Components/Button/Button.tsx +37 -2
  259. package/UI/Components/Card/Card.tsx +6 -0
  260. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +24 -1
  261. package/UI/Components/Dictionary/DictionaryFilterOperator.ts +57 -0
  262. package/UI/Components/DuplicateModel/DuplicateModel.tsx +16 -0
  263. package/UI/Components/Forms/ModelForm.tsx +54 -2
  264. package/UI/Components/List/ListRow.tsx +6 -0
  265. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +34 -7
  266. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +7 -40
  267. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +155 -3
  268. package/UI/Components/ModelDelete/ModelDelete.tsx +20 -0
  269. package/UI/Components/ModelDetail/CardModelDetail.tsx +36 -23
  270. package/UI/Components/ModelList/ModelList.tsx +21 -2
  271. package/UI/Components/ModelList/StaticModelList.tsx +11 -0
  272. package/UI/Components/ModelTable/BaseModelTable.tsx +168 -62
  273. package/UI/Components/ModelTable/ModelTable.tsx +16 -10
  274. package/UI/Components/ModelTable/TableView.tsx +36 -4
  275. package/UI/Components/MoreMenu/MoreMenuItem.tsx +36 -4
  276. package/UI/Components/OrderedStatesList/Item.tsx +6 -0
  277. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +81 -47
  278. package/UI/Components/ResetObjectID/ResetObjectID.tsx +16 -0
  279. package/UI/Components/SavedViews/SavedViewsFacetSection.tsx +242 -0
  280. package/UI/Components/SavedViews/SavedViewsList.ts +168 -0
  281. package/UI/Components/SavedViews/SavedViewsSearchInput.tsx +46 -0
  282. package/UI/Components/SavedViews/SavedViewsShowMoreButton.tsx +44 -0
  283. package/UI/Components/Table/TableRow.tsx +12 -0
  284. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +152 -2
  285. package/UI/Types/UseComponentOutsideClick.ts +47 -0
  286. package/UI/Utils/PermissionGate.ts +277 -0
  287. package/Utils/Dashboard/Components/DashboardSecurityEventsFlowComponent.ts +84 -0
  288. package/Utils/Dashboard/Components/DashboardSecurityEventsListComponent.ts +110 -0
  289. package/Utils/Dashboard/Components/Index.ts +14 -0
  290. package/Utils/Measurement/MeasurementEvaluator.ts +359 -0
  291. package/Utils/Monitor/MonitorSummarySnapshotUtil.ts +1 -0
  292. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +93 -11
  293. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +231 -0
  294. package/Utils/SecurityEvent/GenericNormalizer.ts +208 -0
  295. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +206 -0
  296. package/Utils/SecurityEvent/NormalizerHelpers.ts +263 -0
  297. package/Utils/SecurityEvent/OcsfNormalizer.ts +194 -0
  298. package/Utils/SecurityEvent/SecurityEventNormalizer.ts +82 -0
  299. package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +579 -0
  300. package/Utils/SecurityEvent/UdmNormalizer.ts +442 -0
  301. package/Utils/Telemetry/CrossSignalScope.ts +46 -9
  302. package/Utils/Telemetry/LogErrorPattern.ts +350 -0
  303. package/build/dist/Models/AnalyticsModels/Index.js +10 -0
  304. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  305. package/build/dist/Models/AnalyticsModels/LogCountBaseline.js +159 -0
  306. package/build/dist/Models/AnalyticsModels/LogCountBaseline.js.map +1 -0
  307. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +596 -0
  308. package/build/dist/Models/AnalyticsModels/SecurityEvent.js.map +1 -0
  309. package/build/dist/Models/AnalyticsModels/Span.js +24 -1
  310. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  311. package/build/dist/Models/AnalyticsModels/SpanCountBaseline.js +181 -0
  312. package/build/dist/Models/AnalyticsModels/SpanCountBaseline.js.map +1 -0
  313. package/build/dist/Models/DatabaseModels/Alert.js +43 -0
  314. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  315. package/build/dist/Models/DatabaseModels/AlertMeasurement.js +1143 -0
  316. package/build/dist/Models/DatabaseModels/AlertMeasurement.js.map +1 -0
  317. package/build/dist/Models/DatabaseModels/AlertMeasurementValue.js +523 -0
  318. package/build/dist/Models/DatabaseModels/AlertMeasurementValue.js.map +1 -0
  319. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +9 -2
  320. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  321. package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js +10 -11
  322. package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js.map +1 -1
  323. package/build/dist/Models/DatabaseModels/DetectionRule.js +517 -0
  324. package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -0
  325. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +410 -0
  326. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -0
  327. package/build/dist/Models/DatabaseModels/Incident.js +43 -0
  328. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  329. package/build/dist/Models/DatabaseModels/IncidentMeasurement.js +1143 -0
  330. package/build/dist/Models/DatabaseModels/IncidentMeasurement.js.map +1 -0
  331. package/build/dist/Models/DatabaseModels/IncidentMeasurementValue.js +523 -0
  332. package/build/dist/Models/DatabaseModels/IncidentMeasurementValue.js.map +1 -0
  333. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +9 -2
  334. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  335. package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js +36 -0
  336. package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js +42 -0
  338. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js.map +1 -1
  339. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  340. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  341. package/build/dist/Models/DatabaseModels/Label.js +11 -0
  342. package/build/dist/Models/DatabaseModels/Label.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/LlmCostBudget.js +681 -0
  344. package/build/dist/Models/DatabaseModels/LlmCostBudget.js.map +1 -0
  345. package/build/dist/Models/DatabaseModels/LlmModelPrice.js +503 -0
  346. package/build/dist/Models/DatabaseModels/LlmModelPrice.js.map +1 -0
  347. package/build/dist/Models/DatabaseModels/LogSavedView.js +87 -0
  348. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/MarketingConversion.js +224 -8
  350. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/MetricSavedView.js +59 -0
  352. package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js +36 -0
  354. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js +42 -0
  356. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js +36 -0
  358. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js +42 -0
  360. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/Probe.js +21 -0
  362. package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/RunbookLabelRule.js +36 -0
  364. package/build/dist/Models/DatabaseModels/RunbookLabelRule.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js +42 -0
  366. package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js.map +1 -1
  367. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurement.js +1133 -0
  368. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurement.js.map +1 -0
  369. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurementValue.js +515 -0
  370. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurementValue.js.map +1 -0
  371. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +9 -2
  372. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  373. package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js +36 -0
  374. package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js.map +1 -1
  375. package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js +42 -0
  376. package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js.map +1 -1
  377. package/build/dist/Models/DatabaseModels/TableView.js +15 -0
  378. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
  379. package/build/dist/Models/DatabaseModels/Team.js +13 -0
  380. package/build/dist/Models/DatabaseModels/Team.js.map +1 -1
  381. package/build/dist/Models/DatabaseModels/TeamMember.js +8 -0
  382. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  383. package/build/dist/Models/DatabaseModels/TraceSavedView.js +52 -0
  384. package/build/dist/Models/DatabaseModels/TraceSavedView.js.map +1 -1
  385. package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js +36 -0
  386. package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js.map +1 -1
  387. package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js +42 -0
  388. package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js.map +1 -1
  389. package/build/dist/Server/API/TelemetryAPI.js +136 -0
  390. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  391. package/build/dist/Server/API/UserAPI.js +75 -2
  392. package/build/dist/Server/API/UserAPI.js.map +1 -1
  393. package/build/dist/Server/EnvironmentConfig.js +29 -1
  394. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  395. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788000000000-AddDetectionRuleAndGoogleSecOpsConnection.js +36 -0
  396. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788000000000-AddDetectionRuleAndGoogleSecOpsConnection.js.map +1 -0
  397. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788100000000-AddMeasurements.js +162 -0
  398. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788100000000-AddMeasurements.js.map +1 -0
  399. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788200000000-AddLlmCostBudget.js +40 -0
  400. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788200000000-AddLlmCostBudget.js.map +1 -0
  401. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788300000000-AddLlmModelPrice.js +22 -0
  402. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788300000000-AddLlmModelPrice.js.map +1 -0
  403. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788400000000-AddMarketingConversionAttribution.js +52 -0
  404. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788400000000-AddMarketingConversionAttribution.js.map +1 -0
  405. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788500000000-RemoveLlmCostBudgetAlertColumns.js +38 -0
  406. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788500000000-RemoveLlmCostBudgetAlertColumns.js.map +1 -0
  407. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  408. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  409. package/build/dist/Server/Middleware/IdentityRateLimit.js +491 -0
  410. package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -0
  411. package/build/dist/Server/Services/AccessTokenService.js +13 -2
  412. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  413. package/build/dist/Server/Services/AlertMeasurementService.js +250 -0
  414. package/build/dist/Server/Services/AlertMeasurementService.js.map +1 -0
  415. package/build/dist/Server/Services/AlertMeasurementValueService.js +400 -0
  416. package/build/dist/Server/Services/AlertMeasurementValueService.js.map +1 -0
  417. package/build/dist/Server/Services/AlertService.js +37 -0
  418. package/build/dist/Server/Services/AlertService.js.map +1 -1
  419. package/build/dist/Server/Services/AlertStateTimelineService.js +48 -0
  420. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  421. package/build/dist/Server/Services/DetectionRuleService.js +50 -0
  422. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -0
  423. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +55 -0
  424. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -0
  425. package/build/dist/Server/Services/IncidentMeasurementService.js +252 -0
  426. package/build/dist/Server/Services/IncidentMeasurementService.js.map +1 -0
  427. package/build/dist/Server/Services/IncidentMeasurementValueService.js +413 -0
  428. package/build/dist/Server/Services/IncidentMeasurementValueService.js.map +1 -0
  429. package/build/dist/Server/Services/IncidentService.js +41 -0
  430. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  431. package/build/dist/Server/Services/IncidentStateTimelineService.js +50 -0
  432. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  433. package/build/dist/Server/Services/Index.js +30 -0
  434. package/build/dist/Server/Services/Index.js.map +1 -1
  435. package/build/dist/Server/Services/LlmCostBudgetService.js +89 -0
  436. package/build/dist/Server/Services/LlmCostBudgetService.js.map +1 -0
  437. package/build/dist/Server/Services/LlmModelPriceService.js +163 -0
  438. package/build/dist/Server/Services/LlmModelPriceService.js.map +1 -0
  439. package/build/dist/Server/Services/LogAggregationService.js +709 -0
  440. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  441. package/build/dist/Server/Services/LogCountBaselineService.js +112 -0
  442. package/build/dist/Server/Services/LogCountBaselineService.js.map +1 -0
  443. package/build/dist/Server/Services/MutableMetricService.js +28 -9
  444. package/build/dist/Server/Services/MutableMetricService.js.map +1 -1
  445. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementService.js +254 -0
  446. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementService.js.map +1 -0
  447. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementValueService.js +434 -0
  448. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementValueService.js.map +1 -0
  449. package/build/dist/Server/Services/ScheduledMaintenanceService.js +37 -0
  450. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  451. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +134 -0
  452. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  453. package/build/dist/Server/Services/SecurityEventService.js +64 -0
  454. package/build/dist/Server/Services/SecurityEventService.js.map +1 -0
  455. package/build/dist/Server/Services/SpanCountBaselineService.js +122 -0
  456. package/build/dist/Server/Services/SpanCountBaselineService.js.map +1 -0
  457. package/build/dist/Server/Services/StatusPageService.js +4 -3
  458. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  459. package/build/dist/Server/Services/TelemetryUsageBillingService.js +15 -3
  460. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  461. package/build/dist/Server/Services/UserService.js +262 -42
  462. package/build/dist/Server/Services/UserService.js.map +1 -1
  463. package/build/dist/Server/Services/UserTotpAuthService.js +0 -73
  464. package/build/dist/Server/Services/UserTotpAuthService.js.map +1 -1
  465. package/build/dist/Server/Services/UserWebAuthnService.js +1 -73
  466. package/build/dist/Server/Services/UserWebAuthnService.js.map +1 -1
  467. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +13 -0
  468. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
  469. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +10 -0
  470. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  471. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  472. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  473. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  474. package/build/dist/Server/Utils/AI/Toolbox/Index.js +3 -0
  475. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  476. package/build/dist/Server/Utils/AI/Toolbox/SecurityEventTools.js +257 -0
  477. package/build/dist/Server/Utils/AI/Toolbox/SecurityEventTools.js.map +1 -0
  478. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -4
  479. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  480. package/build/dist/Server/Utils/Attribution.js +77 -33
  481. package/build/dist/Server/Utils/Attribution.js.map +1 -1
  482. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +46 -9
  483. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
  484. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +52 -8
  485. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
  486. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +41 -17
  487. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
  488. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +42 -18
  489. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
  490. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +24 -11
  491. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
  492. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +34 -15
  493. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
  494. package/build/dist/Server/Utils/Measurement/MeasurementDefinitionValidator.js +109 -0
  495. package/build/dist/Server/Utils/Measurement/MeasurementDefinitionValidator.js.map +1 -0
  496. package/build/dist/Server/Utils/Measurement/MeasurementMetricWriter.js +131 -0
  497. package/build/dist/Server/Utils/Measurement/MeasurementMetricWriter.js.map +1 -0
  498. package/build/dist/Server/Utils/Monitor/Criteria/CountAnomaly.js +111 -0
  499. package/build/dist/Server/Utils/Monitor/Criteria/CountAnomaly.js.map +1 -0
  500. package/build/dist/Server/Utils/Monitor/Criteria/LogMonitorCriteria.js +84 -1
  501. package/build/dist/Server/Utils/Monitor/Criteria/LogMonitorCriteria.js.map +1 -1
  502. package/build/dist/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.js +35 -0
  503. package/build/dist/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.js.map +1 -0
  504. package/build/dist/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.js +84 -1
  505. package/build/dist/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.js.map +1 -1
  506. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  507. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  508. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +12 -0
  509. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  510. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
  511. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  512. package/build/dist/Server/Utils/Monitor/MonitorResource.js +10 -0
  513. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  514. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +6 -5
  515. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  516. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +1 -0
  517. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -1
  518. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +404 -0
  519. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -0
  520. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +145 -0
  521. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
  522. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +176 -0
  523. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -0
  524. package/build/dist/Server/Utils/SecurityEvent/SecurityEventRow.js +69 -0
  525. package/build/dist/Server/Utils/SecurityEvent/SecurityEventRow.js.map +1 -0
  526. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +493 -0
  527. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -0
  528. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js +317 -0
  529. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js.map +1 -0
  530. package/build/dist/Server/Utils/Telemetry/LlmSpan.js +56 -4
  531. package/build/dist/Server/Utils/Telemetry/LlmSpan.js.map +1 -1
  532. package/build/dist/Server/Utils/Telemetry/LogErrorPatternSql.js +112 -0
  533. package/build/dist/Server/Utils/Telemetry/LogErrorPatternSql.js.map +1 -0
  534. package/build/dist/Server/Utils/UserPermission/UserPermission.js +46 -1
  535. package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
  536. package/build/dist/Types/AI/AIChatTypes.js +1 -0
  537. package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
  538. package/build/dist/Types/Alerts/AlertMeasurementAnchorType.js +15 -0
  539. package/build/dist/Types/Alerts/AlertMeasurementAnchorType.js.map +1 -0
  540. package/build/dist/Types/Alerts/AlertStateRole.js +12 -0
  541. package/build/dist/Types/Alerts/AlertStateRole.js.map +1 -0
  542. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +16 -0
  543. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  544. package/build/dist/Types/Dashboard/Chart/ChartType.js +1 -0
  545. package/build/dist/Types/Dashboard/Chart/ChartType.js.map +1 -1
  546. package/build/dist/Types/Dashboard/DashboardComponentType.js +2 -0
  547. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  548. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsFlowComponent.js +2 -0
  549. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsFlowComponent.js.map +1 -0
  550. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsListComponent.js +2 -0
  551. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsListComponent.js.map +1 -0
  552. package/build/dist/Types/Incident/IncidentMeasurementAnchorType.js +29 -0
  553. package/build/dist/Types/Incident/IncidentMeasurementAnchorType.js.map +1 -0
  554. package/build/dist/Types/Incident/IncidentStateRole.js +15 -0
  555. package/build/dist/Types/Incident/IncidentStateRole.js.map +1 -0
  556. package/build/dist/Types/Marketing/Attribution.js +68 -0
  557. package/build/dist/Types/Marketing/Attribution.js.map +1 -0
  558. package/build/dist/Types/Marketing/MarketingConversion.js +36 -7
  559. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
  560. package/build/dist/Types/Measurement/MeasurementAggregationType.js +40 -0
  561. package/build/dist/Types/Measurement/MeasurementAggregationType.js.map +1 -0
  562. package/build/dist/Types/Measurement/MeasurementAnchorKind.js +22 -0
  563. package/build/dist/Types/Measurement/MeasurementAnchorKind.js.map +1 -0
  564. package/build/dist/Types/Measurement/MeasurementOccurrence.js +15 -0
  565. package/build/dist/Types/Measurement/MeasurementOccurrence.js.map +1 -0
  566. package/build/dist/Types/Measurement/MeasurementStatus.js +32 -0
  567. package/build/dist/Types/Measurement/MeasurementStatus.js.map +1 -0
  568. package/build/dist/Types/MeteredPlan/ProductType.js +1 -0
  569. package/build/dist/Types/MeteredPlan/ProductType.js.map +1 -1
  570. package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
  571. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  572. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +59 -0
  573. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  574. package/build/dist/Types/Monitor/MonitorStep.js +17 -0
  575. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  576. package/build/dist/Types/Monitor/MonitorStepSecurityEventsMonitor.js +64 -0
  577. package/build/dist/Types/Monitor/MonitorStepSecurityEventsMonitor.js.map +1 -0
  578. package/build/dist/Types/Monitor/MonitorType.js +19 -0
  579. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  580. package/build/dist/Types/Monitor/SecurityEventsMonitor/SecurityEventsMonitorResponse.js +2 -0
  581. package/build/dist/Types/Monitor/SecurityEventsMonitor/SecurityEventsMonitorResponse.js.map +1 -0
  582. package/build/dist/Types/Permission.js +347 -2
  583. package/build/dist/Types/Permission.js.map +1 -1
  584. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceMeasurementAnchorType.js +19 -0
  585. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceMeasurementAnchorType.js.map +1 -0
  586. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceStateRole.js +17 -0
  587. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceStateRole.js.map +1 -0
  588. package/build/dist/Types/SecurityEvent/NormalizedSecurityEvent.js +2 -0
  589. package/build/dist/Types/SecurityEvent/NormalizedSecurityEvent.js.map +1 -0
  590. package/build/dist/Types/SecurityEvent/OcsfEventClass.js +181 -0
  591. package/build/dist/Types/SecurityEvent/OcsfEventClass.js.map +1 -0
  592. package/build/dist/Types/SecurityEvent/OcsfSeverity.js +81 -0
  593. package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -0
  594. package/build/dist/Types/SecurityEvent/SecurityEventFormat.js +21 -0
  595. package/build/dist/Types/SecurityEvent/SecurityEventFormat.js.map +1 -0
  596. package/build/dist/Types/SecurityEvent/SigmaRule.js +16 -0
  597. package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -0
  598. package/build/dist/Types/Telemetry/LlmConventions.js +19 -1
  599. package/build/dist/Types/Telemetry/LlmConventions.js.map +1 -1
  600. package/build/dist/Types/Telemetry/LlmCostCatalog.js +484 -0
  601. package/build/dist/Types/Telemetry/LlmCostCatalog.js.map +1 -0
  602. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  603. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  604. package/build/dist/Types/Telemetry/TelemetryRetentionConfig.js.map +1 -1
  605. package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
  606. package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
  607. package/build/dist/Types/TwoFactorAuthStatus.js +41 -0
  608. package/build/dist/Types/TwoFactorAuthStatus.js.map +1 -0
  609. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +16 -2
  610. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
  611. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +15 -1
  612. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  613. package/build/dist/UI/Components/BulkUpdate/BulkOwnerActions.js +20 -1
  614. package/build/dist/UI/Components/BulkUpdate/BulkOwnerActions.js.map +1 -1
  615. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +1 -1
  616. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  617. package/build/dist/UI/Components/Button/Button.js +22 -1
  618. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  619. package/build/dist/UI/Components/Card/Card.js +1 -1
  620. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  621. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +14 -1
  622. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  623. package/build/dist/UI/Components/Dictionary/DictionaryFilterOperator.js +47 -0
  624. package/build/dist/UI/Components/Dictionary/DictionaryFilterOperator.js.map +1 -1
  625. package/build/dist/UI/Components/DuplicateModel/DuplicateModel.js +8 -0
  626. package/build/dist/UI/Components/DuplicateModel/DuplicateModel.js.map +1 -1
  627. package/build/dist/UI/Components/Forms/ModelForm.js +40 -1
  628. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  629. package/build/dist/UI/Components/List/ListRow.js +4 -1
  630. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  631. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +32 -7
  632. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  633. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +2 -17
  634. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  635. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +93 -4
  636. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  637. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +13 -0
  638. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  639. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +27 -11
  640. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  641. package/build/dist/UI/Components/ModelList/ModelList.js +13 -2
  642. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  643. package/build/dist/UI/Components/ModelList/StaticModelList.js +4 -1
  644. package/build/dist/UI/Components/ModelList/StaticModelList.js.map +1 -1
  645. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +101 -40
  646. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  647. package/build/dist/UI/Components/ModelTable/ModelTable.js +9 -7
  648. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  649. package/build/dist/UI/Components/ModelTable/TableView.js +32 -4
  650. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  651. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +19 -2
  652. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  653. package/build/dist/UI/Components/OrderedStatesList/Item.js +4 -1
  654. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  655. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +33 -32
  656. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  657. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +8 -0
  658. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
  659. package/build/dist/UI/Components/SavedViews/SavedViewsFacetSection.js +98 -0
  660. package/build/dist/UI/Components/SavedViews/SavedViewsFacetSection.js.map +1 -0
  661. package/build/dist/UI/Components/SavedViews/SavedViewsList.js +99 -0
  662. package/build/dist/UI/Components/SavedViews/SavedViewsList.js.map +1 -0
  663. package/build/dist/UI/Components/SavedViews/SavedViewsSearchInput.js +17 -0
  664. package/build/dist/UI/Components/SavedViews/SavedViewsSearchInput.js.map +1 -0
  665. package/build/dist/UI/Components/SavedViews/SavedViewsShowMoreButton.js +15 -0
  666. package/build/dist/UI/Components/SavedViews/SavedViewsShowMoreButton.js.map +1 -0
  667. package/build/dist/UI/Components/Table/TableRow.js +8 -2
  668. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  669. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +93 -4
  670. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  671. package/build/dist/UI/Types/UseComponentOutsideClick.js +39 -0
  672. package/build/dist/UI/Types/UseComponentOutsideClick.js.map +1 -1
  673. package/build/dist/UI/Utils/PermissionGate.js +164 -0
  674. package/build/dist/UI/Utils/PermissionGate.js.map +1 -0
  675. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsFlowComponent.js +70 -0
  676. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsFlowComponent.js.map +1 -0
  677. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsListComponent.js +92 -0
  678. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsListComponent.js.map +1 -0
  679. package/build/dist/Utils/Dashboard/Components/Index.js +8 -0
  680. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  681. package/build/dist/Utils/Measurement/MeasurementEvaluator.js +210 -0
  682. package/build/dist/Utils/Measurement/MeasurementEvaluator.js.map +1 -0
  683. package/build/dist/Utils/Monitor/MonitorSummarySnapshotUtil.js +1 -0
  684. package/build/dist/Utils/Monitor/MonitorSummarySnapshotUtil.js.map +1 -1
  685. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +51 -10
  686. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
  687. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +108 -0
  688. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -0
  689. package/build/dist/Utils/SecurityEvent/GenericNormalizer.js +176 -0
  690. package/build/dist/Utils/SecurityEvent/GenericNormalizer.js.map +1 -0
  691. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +146 -0
  692. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -0
  693. package/build/dist/Utils/SecurityEvent/NormalizerHelpers.js +196 -0
  694. package/build/dist/Utils/SecurityEvent/NormalizerHelpers.js.map +1 -0
  695. package/build/dist/Utils/SecurityEvent/OcsfNormalizer.js +136 -0
  696. package/build/dist/Utils/SecurityEvent/OcsfNormalizer.js.map +1 -0
  697. package/build/dist/Utils/SecurityEvent/SecurityEventNormalizer.js +64 -0
  698. package/build/dist/Utils/SecurityEvent/SecurityEventNormalizer.js.map +1 -0
  699. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +388 -0
  700. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -0
  701. package/build/dist/Utils/SecurityEvent/UdmNormalizer.js +328 -0
  702. package/build/dist/Utils/SecurityEvent/UdmNormalizer.js.map +1 -0
  703. package/build/dist/Utils/Telemetry/CrossSignalScope.js +29 -7
  704. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  705. package/build/dist/Utils/Telemetry/LogErrorPattern.js +284 -0
  706. package/build/dist/Utils/Telemetry/LogErrorPattern.js.map +1 -0
  707. package/package.json +3 -1
@@ -0,0 +1,804 @@
1
+ import LogAggregationService, {
2
+ DEFAULT_ERROR_LOG_SEVERITIES,
3
+ ErrorPatternAttribute,
4
+ ErrorPatternCoOccurrence,
5
+ ErrorPatternResource,
6
+ ErrorPatternSample,
7
+ ErrorPatternTimelinePoint,
8
+ ErrorPatternTrace,
9
+ TopErrorPattern,
10
+ } from "../../../Server/Services/LogAggregationService";
11
+ import LogDatabaseService from "../../../Server/Services/LogService";
12
+ import { Results } from "../../../Server/Services/AnalyticsDatabaseService";
13
+ import { Statement } from "../../../Server/Utils/AnalyticsDatabase/Statement";
14
+ import {
15
+ LOG_ERROR_PATTERN_MAX_LENGTH,
16
+ normalizeLogBodyToErrorPattern,
17
+ } from "../../../Utils/Telemetry/LogErrorPattern";
18
+ import { JSONObject } from "../../../Types/JSON";
19
+ import ObjectID from "../../../Types/ObjectID";
20
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
21
+
22
+ /*
23
+ * The error-pattern reads are what turn the Logs Insights page from a pile
24
+ * of counters into an answer. Every one of them has to satisfy the same
25
+ * three properties, which is what this suite pins:
26
+ *
27
+ * 1. the clustering happens in ClickHouse, over the whole window;
28
+ * 2. every drill-down sees EXACTLY the slice the top-list saw (same
29
+ * window, same severities, same resource scope) — a panel that
30
+ * quietly widened its own scope would show correlations that are not
31
+ * real;
32
+ * 3. nothing a caller supplies reaches the SQL text.
33
+ */
34
+
35
+ const projectId: ObjectID = ObjectID.generate();
36
+ const startTime: Date = new Date("2026-08-19T00:00:00.000Z");
37
+ const endTime: Date = new Date("2026-08-21T00:00:00.000Z");
38
+ const pattern: string = "connection refused to <ip>:<num>";
39
+
40
+ /*
41
+ * Stub the ClickHouse boundary and capture the Statements handed to it, so
42
+ * the public (async) read methods can be exercised without a database —
43
+ * the same pattern the sibling LogAggregationService suite uses.
44
+ */
45
+ function stubAndCapture(rows: Array<JSONObject>): Array<Statement> {
46
+ const captured: Array<Statement> = [];
47
+ const fakeResult: Results = {
48
+ json: () => {
49
+ return Promise.resolve({ data: rows });
50
+ },
51
+ } as unknown as Results;
52
+
53
+ jest
54
+ .spyOn(LogDatabaseService, "executeQuery")
55
+ .mockImplementation((statement: Statement | string): Promise<Results> => {
56
+ captured.push(statement as Statement);
57
+ return Promise.resolve(fakeResult);
58
+ });
59
+
60
+ return captured;
61
+ }
62
+
63
+ function baseFilters(): {
64
+ projectId: ObjectID;
65
+ startTime: Date;
66
+ endTime: Date;
67
+ } {
68
+ return { projectId, startTime, endTime };
69
+ }
70
+
71
+ function detailRequest(overrides: Record<string, unknown> = {}): any {
72
+ return {
73
+ ...baseFilters(),
74
+ pattern,
75
+ bucketSizeInMinutes: 60,
76
+ ...overrides,
77
+ };
78
+ }
79
+
80
+ /** Every async error-pattern read, so shared invariants can be swept. */
81
+ const DETAIL_READS: Array<{
82
+ name: string;
83
+ run: (request: any) => Promise<unknown>;
84
+ }> = [
85
+ {
86
+ name: "timeline",
87
+ run: (request: any) => {
88
+ return LogAggregationService.getErrorPatternTimeline(request);
89
+ },
90
+ },
91
+ {
92
+ name: "co-occurrences",
93
+ run: (request: any) => {
94
+ return LogAggregationService.getErrorPatternCoOccurrences(request);
95
+ },
96
+ },
97
+ {
98
+ name: "attributes",
99
+ run: (request: any) => {
100
+ return LogAggregationService.getErrorPatternAttributes(request);
101
+ },
102
+ },
103
+ {
104
+ name: "resources",
105
+ run: (request: any) => {
106
+ return LogAggregationService.getErrorPatternResources(request);
107
+ },
108
+ },
109
+ {
110
+ name: "traces",
111
+ run: (request: any) => {
112
+ return LogAggregationService.getErrorPatternTraces(request);
113
+ },
114
+ },
115
+ {
116
+ name: "samples",
117
+ run: (request: any) => {
118
+ return LogAggregationService.getErrorPatternSamples(request);
119
+ },
120
+ },
121
+ ];
122
+
123
+ afterEach(() => {
124
+ jest.restoreAllMocks();
125
+ });
126
+
127
+ describe("getTopErrorPatterns", () => {
128
+ test("groups in the database and returns one row per pattern", async () => {
129
+ const captured: Array<Statement> = stubAndCapture([
130
+ {
131
+ pattern,
132
+ cnt: 30,
133
+ sampleBody: "connection refused to 10.0.0.4:5432",
134
+ firstSeen: "2026-08-19 03:00:00.000000000",
135
+ lastSeen: "2026-08-20 22:14:02.000000000",
136
+ resourceCount: 2,
137
+ resourceIds: ["svc-a", "svc-b"],
138
+ severities: ["Error"],
139
+ traceCount: 4,
140
+ sampleTraceIds: ["t1", "t2"],
141
+ },
142
+ ]);
143
+
144
+ const patterns: Array<TopErrorPattern> =
145
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
146
+
147
+ expect(captured.length).toBe(1);
148
+ expect(captured[0]!.query).toContain("GROUP BY pattern");
149
+ expect(captured[0]!.query).toContain("ORDER BY cnt DESC");
150
+ // GROUP BY -> HAVING -> ORDER BY -> LIMIT, in that order.
151
+ expect(captured[0]!.query).toMatch(
152
+ /GROUP BY pattern HAVING pattern != '' ORDER BY cnt DESC LIMIT/,
153
+ );
154
+ expect(captured[0]!.query).toContain("replaceRegexpAll(");
155
+
156
+ expect(patterns).toEqual([
157
+ {
158
+ pattern,
159
+ sampleBody: "connection refused to 10.0.0.4:5432",
160
+ count: 30,
161
+ firstSeenAt: "2026-08-19 03:00:00.000000000",
162
+ lastSeenAt: "2026-08-20 22:14:02.000000000",
163
+ resourceCount: 2,
164
+ resourceIds: ["svc-a", "svc-b"],
165
+ severities: ["Error"],
166
+ traceCount: 4,
167
+ sampleTraceIds: ["t1", "t2"],
168
+ },
169
+ ]);
170
+ });
171
+
172
+ test("selects the first-seen, last-seen and reach columns the list needs", async () => {
173
+ const captured: Array<Statement> = stubAndCapture([]);
174
+
175
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
176
+
177
+ const query: string = captured[0]!.query;
178
+
179
+ expect(query).toContain("min(time) AS firstSeen");
180
+ expect(query).toContain("max(time) AS lastSeen");
181
+ expect(query).toContain("uniqExact(primaryEntityId) AS resourceCount");
182
+ expect(query).toContain("argMax(ifNull(body, ''), time) AS sampleBody");
183
+ /*
184
+ * Trace reach must ignore the Nullable column's NULLs explicitly:
185
+ * `traceId != ''` alone is NULL for a log with no trace, and a NULL
186
+ * condition is not a counted one.
187
+ */
188
+ expect(query).toContain(
189
+ "uniqExactIf(traceId, ifNull(traceId, '') != '') AS traceCount",
190
+ );
191
+ });
192
+
193
+ test("defaults to Error and Fatal when the caller names no severities", async () => {
194
+ const captured: Array<Statement> = stubAndCapture([]);
195
+
196
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
197
+
198
+ expect(captured[0]!.query).toContain("AND severityText IN (");
199
+ expect(Object.values(captured[0]!.query_params)).toContainEqual(
200
+ DEFAULT_ERROR_LOG_SEVERITIES,
201
+ );
202
+ });
203
+
204
+ test("an explicit severity selection replaces the default", async () => {
205
+ const captured: Array<Statement> = stubAndCapture([]);
206
+
207
+ await LogAggregationService.getTopErrorPatterns({
208
+ ...baseFilters(),
209
+ severityTexts: ["Warning"],
210
+ });
211
+
212
+ expect(Object.values(captured[0]!.query_params)).toContainEqual([
213
+ "Warning",
214
+ ]);
215
+ expect(Object.values(captured[0]!.query_params)).not.toContainEqual(
216
+ DEFAULT_ERROR_LOG_SEVERITIES,
217
+ );
218
+ });
219
+
220
+ test("an empty severity array is treated as 'not specified', not as 'match nothing'", async () => {
221
+ const captured: Array<Statement> = stubAndCapture([]);
222
+
223
+ await LogAggregationService.getTopErrorPatterns({
224
+ ...baseFilters(),
225
+ severityTexts: [],
226
+ });
227
+
228
+ expect(Object.values(captured[0]!.query_params)).toContainEqual(
229
+ DEFAULT_ERROR_LOG_SEVERITIES,
230
+ );
231
+ });
232
+
233
+ test("guards against an empty-pattern group with BOTH a prefilter and a HAVING", async () => {
234
+ const captured: Array<Statement> = stubAndCapture([]);
235
+
236
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
237
+
238
+ const query: string = captured[0]!.query;
239
+
240
+ // The cheap early skip...
241
+ expect(query).toContain("AND notEmpty(trimBoth(ifNull(body, '')))");
242
+
243
+ /*
244
+ * ...and the actual guarantee. The prefilter alone is NOT enough:
245
+ * ClickHouse's trimBoth strips spaces only, so a body of tabs or
246
+ * newlines survives it and still normalizes to "" once the whitespace
247
+ * rule collapses it — silently consuming one of the LIMIT slots. Pinned
248
+ * here because the prefilter-only assertion this test used to make
249
+ * passed while that bug was live.
250
+ */
251
+ expect(query).toContain("GROUP BY pattern HAVING pattern != ''");
252
+ });
253
+
254
+ test("the empty pattern a tab-only body produces is what the HAVING excludes", () => {
255
+ /*
256
+ * Ties the SQL guard to the behaviour it exists for: this is the exact
257
+ * value such a row groups under, and it is the value the HAVING drops.
258
+ */
259
+ expect(normalizeLogBodyToErrorPattern("\t\n\t")).toBe("");
260
+ });
261
+
262
+ test("applies the read-side retention filter", async () => {
263
+ const captured: Array<Statement> = stubAndCapture([]);
264
+
265
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
266
+
267
+ expect(captured[0]!.query).toContain("AND retentionDate >= now()");
268
+ });
269
+
270
+ test("threads the service scope into the read", async () => {
271
+ const serviceId: ObjectID = ObjectID.generate();
272
+ const captured: Array<Statement> = stubAndCapture([]);
273
+
274
+ await LogAggregationService.getTopErrorPatterns({
275
+ ...baseFilters(),
276
+ serviceIds: [serviceId],
277
+ });
278
+
279
+ expect(captured[0]!.query).toMatch(
280
+ /AND primaryEntityId IN \(\{p\d+:Array\(String\)\}\)/,
281
+ );
282
+ expect(Object.values(captured[0]!.query_params)).toContainEqual([
283
+ serviceId.toString(),
284
+ ]);
285
+ });
286
+
287
+ test("threads entity keys, trace/span/session scope and attribute filters", async () => {
288
+ const captured: Array<Statement> = stubAndCapture([]);
289
+
290
+ await LogAggregationService.getTopErrorPatterns({
291
+ ...baseFilters(),
292
+ entityKeys: ["host-key-1"],
293
+ traceIds: ["trace-1"],
294
+ spanIds: ["span-1"],
295
+ sessionIds: ["sess-1"],
296
+ attributes: { "k8s.pod.name": "checkout-7d9" },
297
+ });
298
+
299
+ const query: string = captured[0]!.query;
300
+ const values: Array<unknown> = Object.values(captured[0]!.query_params);
301
+
302
+ expect(query).toContain("hasAny(entityKeys,");
303
+ expect(query).toMatch(/AND traceId IN \(\{p\d+:Array\(String\)\}\)/);
304
+ expect(query).toMatch(/AND spanId IN \(\{p\d+:Array\(String\)\}\)/);
305
+ expect(query).toMatch(/AND sessionId IN \(\{p\d+:Array\(String\)\}\)/);
306
+ expect(query).toContain("arrayExists((k, v) -> lowerUTF8(k) = lowerUTF8(");
307
+ expect(values).toContainEqual(["host-key-1"]);
308
+ expect(values).toContain("checkout-7d9");
309
+ });
310
+
311
+ test("clamps the limit into range and defaults when it is absent or nonsense", async () => {
312
+ const limitOf: (statement: Statement) => number = (
313
+ statement: Statement,
314
+ ): number => {
315
+ const numbers: Array<number> = Object.values(
316
+ statement.query_params,
317
+ ).filter((value: unknown): value is number => {
318
+ return typeof value === "number";
319
+ });
320
+
321
+ // The trailing LIMIT is the last bound number in the statement.
322
+ return numbers[numbers.length - 1]!;
323
+ };
324
+
325
+ const captured: Array<Statement> = stubAndCapture([]);
326
+
327
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
328
+ expect(limitOf(captured[0]!)).toBe(10);
329
+
330
+ await LogAggregationService.getTopErrorPatterns({
331
+ ...baseFilters(),
332
+ limit: 5000,
333
+ });
334
+ expect(limitOf(captured[1]!)).toBe(50);
335
+
336
+ await LogAggregationService.getTopErrorPatterns({
337
+ ...baseFilters(),
338
+ limit: 0,
339
+ });
340
+ expect(limitOf(captured[2]!)).toBe(1);
341
+
342
+ await LogAggregationService.getTopErrorPatterns({
343
+ ...baseFilters(),
344
+ limit: Number.NaN,
345
+ });
346
+ expect(limitOf(captured[3]!)).toBe(10);
347
+ });
348
+
349
+ test("drops rows whose pattern came back empty", async () => {
350
+ stubAndCapture([
351
+ { pattern: "", cnt: 9 },
352
+ { pattern, cnt: 3 },
353
+ ]);
354
+
355
+ const patterns: Array<TopErrorPattern> =
356
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
357
+
358
+ expect(
359
+ patterns.map((p: TopErrorPattern) => {
360
+ return p.pattern;
361
+ }),
362
+ ).toEqual([pattern]);
363
+ });
364
+
365
+ test("coerces malformed array aggregates instead of throwing", async () => {
366
+ stubAndCapture([
367
+ {
368
+ pattern,
369
+ cnt: "12",
370
+ resourceIds: "not-an-array",
371
+ severities: ["Error", null, ""],
372
+ sampleTraceIds: null,
373
+ },
374
+ ]);
375
+
376
+ const patterns: Array<TopErrorPattern> =
377
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
378
+
379
+ expect(patterns[0]!.count).toBe(12);
380
+ expect(patterns[0]!.resourceIds).toEqual([]);
381
+ expect(patterns[0]!.severities).toEqual(["Error"]);
382
+ expect(patterns[0]!.sampleTraceIds).toEqual([]);
383
+ });
384
+
385
+ test("caps the sampled id arrays so a hot pattern cannot return a huge row", async () => {
386
+ const captured: Array<Statement> = stubAndCapture([]);
387
+
388
+ await LogAggregationService.getTopErrorPatterns(baseFilters());
389
+
390
+ /*
391
+ * Inlined constants, not bound parameters: these are the parameters of
392
+ * a parametric aggregate function, which ClickHouse requires to be
393
+ * constants.
394
+ */
395
+ expect(captured[0]!.query).toContain(
396
+ "groupUniqArray(5)(toString(primaryEntityId)) AS resourceIds",
397
+ );
398
+ expect(captured[0]!.query).toContain(
399
+ "groupUniqArray(8)(toString(severityText)) AS severities",
400
+ );
401
+ expect(captured[0]!.query).toContain(
402
+ "groupUniqArrayIf(5)(ifNull(traceId, ''), ifNull(traceId, '') != '') AS sampleTraceIds",
403
+ );
404
+ });
405
+ });
406
+
407
+ describe("error-pattern drill-downs share the top list's scope", () => {
408
+ test.each(DETAIL_READS)(
409
+ "$name scopes to the pattern, the window and the default severities",
410
+ async ({ run }: { run: (request: any) => Promise<unknown> }) => {
411
+ const captured: Array<Statement> = stubAndCapture([]);
412
+
413
+ await run(detailRequest());
414
+
415
+ const statement: Statement = captured[0]!;
416
+ const values: Array<unknown> = Object.values(statement.query_params);
417
+
418
+ expect(statement.query).toContain("replaceRegexpAll(");
419
+ expect(values).toContain(pattern);
420
+ expect(values).toContainEqual(DEFAULT_ERROR_LOG_SEVERITIES);
421
+ expect(statement.query).toContain("AND retentionDate >= now()");
422
+ expect(statement.query).toContain(
423
+ "AND notEmpty(trimBoth(ifNull(body, '')))",
424
+ );
425
+ },
426
+ );
427
+
428
+ test.each(DETAIL_READS)(
429
+ "$name carries the caller's service scope",
430
+ async ({ run }: { run: (request: any) => Promise<unknown> }) => {
431
+ const serviceId: ObjectID = ObjectID.generate();
432
+ const captured: Array<Statement> = stubAndCapture([]);
433
+
434
+ await run(detailRequest({ serviceIds: [serviceId] }));
435
+
436
+ expect(Object.values(captured[0]!.query_params)).toContainEqual([
437
+ serviceId.toString(),
438
+ ]);
439
+ },
440
+ );
441
+
442
+ test.each(DETAIL_READS)(
443
+ "$name never puts the caller's pattern into the query text",
444
+ async ({ run }: { run: (request: any) => Promise<unknown> }) => {
445
+ const injection: string =
446
+ "x' OR 1=1 UNION ALL SELECT version() FROM system.one -- ";
447
+ const captured: Array<Statement> = stubAndCapture([]);
448
+
449
+ await run(detailRequest({ pattern: injection }));
450
+
451
+ expect(captured[0]!.query).not.toContain("UNION");
452
+ expect(captured[0]!.query).not.toContain(injection);
453
+ expect(Object.values(captured[0]!.query_params)).toContain(injection);
454
+ },
455
+ );
456
+
457
+ test.each(DETAIL_READS)(
458
+ "$name clamps an oversized pattern to the expression's own maximum",
459
+ async ({ run }: { run: (request: any) => Promise<unknown> }) => {
460
+ const oversized: string = "y".repeat(LOG_ERROR_PATTERN_MAX_LENGTH * 4);
461
+ const captured: Array<Statement> = stubAndCapture([]);
462
+
463
+ await run(detailRequest({ pattern: oversized }));
464
+
465
+ const echoed: Array<string> = Object.values(
466
+ captured[0]!.query_params,
467
+ ).filter((value: unknown): value is string => {
468
+ return typeof value === "string" && value.startsWith("yyy");
469
+ });
470
+
471
+ expect(echoed.length).toBeGreaterThan(0);
472
+ for (const value of echoed) {
473
+ expect(value.length).toBe(LOG_ERROR_PATTERN_MAX_LENGTH);
474
+ }
475
+ },
476
+ );
477
+
478
+ test.each(DETAIL_READS)(
479
+ "$name emits balanced parens and binds every placeholder it references",
480
+ async ({ run }: { run: (request: any) => Promise<unknown> }) => {
481
+ /*
482
+ * None of these statements has ever been executed against a real
483
+ * ClickHouse, so a stray paren or an unbound {pN} would first surface
484
+ * as a syntax error on a user's dashboard. Cheap to pin here.
485
+ */
486
+ const captured: Array<Statement> = stubAndCapture([]);
487
+
488
+ await run(detailRequest({ serviceIds: [ObjectID.generate()] }));
489
+
490
+ const query: string = captured[0]!.query;
491
+
492
+ let depth: number = 0;
493
+
494
+ for (const character of query) {
495
+ if (character === "(") {
496
+ depth++;
497
+ }
498
+
499
+ if (character === ")") {
500
+ depth--;
501
+ }
502
+
503
+ // Never closes more than it opened at any point.
504
+ expect(depth).toBeGreaterThanOrEqual(0);
505
+ }
506
+
507
+ expect(depth).toBe(0);
508
+
509
+ const referenced: Array<string> = Array.from(
510
+ query.matchAll(/\{(p\d+):/g),
511
+ ).map((match: RegExpMatchArray): string => {
512
+ return match[1] as string;
513
+ });
514
+
515
+ expect(referenced.length).toBeGreaterThan(0);
516
+
517
+ for (const name of referenced) {
518
+ expect(captured[0]!.query_params).toHaveProperty(name);
519
+ }
520
+
521
+ // Every read stays tenant-scoped, on every path.
522
+ expect(query).toContain("WHERE projectId = ");
523
+ },
524
+ );
525
+
526
+ test.each(DETAIL_READS)(
527
+ "$name bounds its runtime below the client request timeout",
528
+ async ({ run }: { run: (request: any) => Promise<unknown> }) => {
529
+ const captured: Array<Statement> = stubAndCapture([]);
530
+
531
+ await run(detailRequest());
532
+
533
+ expect(captured[0]!.query).toContain("max_execution_time = 45");
534
+ expect(captured[0]!.query).toContain("timeout_overflow_mode = 'break'");
535
+ expect(captured[0]!.query).toContain("max_memory_usage =");
536
+ },
537
+ );
538
+ });
539
+
540
+ describe("getErrorPatternTimeline", () => {
541
+ test("buckets by the requested interval, in seconds", async () => {
542
+ const captured: Array<Statement> = stubAndCapture([]);
543
+
544
+ await LogAggregationService.getErrorPatternTimeline(
545
+ detailRequest({ bucketSizeInMinutes: 15 }),
546
+ );
547
+
548
+ expect(captured[0]!.query).toMatch(
549
+ /toStartOfInterval\(time, INTERVAL \{p\d+:Int32\} SECOND\) AS bucket/,
550
+ );
551
+ expect(Object.values(captured[0]!.query_params)).toContain(15 * 60);
552
+ expect(captured[0]!.query).toContain("ORDER BY bucket ASC");
553
+ });
554
+
555
+ test.each([0, -5, Number.NaN, undefined])(
556
+ "an unusable bucket size (%s) never compiles to INTERVAL 0",
557
+ async (bucketSizeInMinutes: number | undefined) => {
558
+ const captured: Array<Statement> = stubAndCapture([]);
559
+
560
+ await LogAggregationService.getErrorPatternTimeline(
561
+ detailRequest({ bucketSizeInMinutes }),
562
+ );
563
+
564
+ const seconds: Array<number> = Object.values(
565
+ captured[0]!.query_params,
566
+ ).filter((value: unknown): value is number => {
567
+ return typeof value === "number";
568
+ });
569
+
570
+ for (const value of seconds) {
571
+ expect(value).toBeGreaterThan(0);
572
+ }
573
+ },
574
+ );
575
+
576
+ test("maps rows to time/count points", async () => {
577
+ stubAndCapture([
578
+ { bucket: "2026-08-20 10:00:00.000000000", cnt: 4 },
579
+ { bucket: "2026-08-20 11:00:00.000000000", cnt: 0 },
580
+ ]);
581
+
582
+ const points: Array<ErrorPatternTimelinePoint> =
583
+ await LogAggregationService.getErrorPatternTimeline(detailRequest());
584
+
585
+ expect(points).toEqual([
586
+ { time: "2026-08-20 10:00:00.000000000", count: 4 },
587
+ { time: "2026-08-20 11:00:00.000000000", count: 0 },
588
+ ]);
589
+ });
590
+ });
591
+
592
+ describe("getErrorPatternCoOccurrences", () => {
593
+ test("restricts to the buckets the investigated pattern landed in, and excludes itself", async () => {
594
+ const captured: Array<Statement> = stubAndCapture([]);
595
+
596
+ await LogAggregationService.getErrorPatternCoOccurrences(detailRequest());
597
+
598
+ const query: string = captured[0]!.query;
599
+
600
+ // The self-exclusion...
601
+ expect(query).toMatch(/!= \{p\d+:String\}/);
602
+ // ...the same empty-pattern guard the top list carries...
603
+ expect(query).toContain("GROUP BY pattern HAVING pattern != ''");
604
+ // ...and the temporal join onto the investigated pattern's own buckets.
605
+ /*
606
+ * GLOBAL IN, not plain IN. LogItemV3 is a Distributed table, and a
607
+ * subquery on the same Distributed table inside its own WHERE is
608
+ * rejected by multi-shard ClickHouse (Code 288,
609
+ * distributed_product_mode = 'deny'). Because the endpoint wraps each
610
+ * correlation read in a degrade-to-empty catch, plain IN fails SILENTLY
611
+ * — the panel just says "nothing else was failing" forever.
612
+ */
613
+ expect(query).toContain(
614
+ "GLOBAL IN (SELECT DISTINCT toStartOfInterval(time,",
615
+ );
616
+ expect(query).toContain("GROUP BY pattern");
617
+ });
618
+
619
+ test("the inner bucket subquery is scoped identically to the outer read", async () => {
620
+ const serviceId: ObjectID = ObjectID.generate();
621
+ const captured: Array<Statement> = stubAndCapture([]);
622
+
623
+ await LogAggregationService.getErrorPatternCoOccurrences(
624
+ detailRequest({ serviceIds: [serviceId] }),
625
+ );
626
+
627
+ const query: string = captured[0]!.query;
628
+
629
+ /*
630
+ * Two WHERE clauses (outer + subquery), two retention filters, two
631
+ * severity predicates, two service predicates. A subquery that skipped
632
+ * any of them would collect buckets from logs the outer query cannot
633
+ * see, and every "co-occurring" error would be correlated against the
634
+ * wrong timeline.
635
+ */
636
+ expect((query.match(/ WHERE projectId = /g) || []).length).toBe(2);
637
+ expect((query.match(/AND retentionDate >= now\(\)/g) || []).length).toBe(2);
638
+ expect((query.match(/AND severityText IN \(/g) || []).length).toBe(2);
639
+ expect((query.match(/AND primaryEntityId IN \(/g) || []).length).toBe(2);
640
+ });
641
+
642
+ test("maps rows and drops empty patterns", async () => {
643
+ stubAndCapture([
644
+ { pattern: "upstream timed out", cnt: 7, sampleBody: "upstream timed" },
645
+ { pattern: "", cnt: 3 },
646
+ ]);
647
+
648
+ const rows: Array<ErrorPatternCoOccurrence> =
649
+ await LogAggregationService.getErrorPatternCoOccurrences(detailRequest());
650
+
651
+ expect(rows).toEqual([
652
+ { pattern: "upstream timed out", count: 7, sampleBody: "upstream timed" },
653
+ ]);
654
+ });
655
+ });
656
+
657
+ describe("getErrorPatternAttributes", () => {
658
+ test("array-joins over a pre-filtered subquery, not the raw table", async () => {
659
+ const captured: Array<Statement> = stubAndCapture([]);
660
+
661
+ await LogAggregationService.getErrorPatternAttributes(detailRequest());
662
+
663
+ const query: string = captured[0]!.query;
664
+
665
+ /*
666
+ * Written flat, the ARRAY JOIN explodes the whole window into one row
667
+ * per attribute before the pattern predicate narrows it. The subquery
668
+ * is what keeps a tooltip-sized answer from costing a twentyfold scan.
669
+ */
670
+ expect(query).toContain("FROM (SELECT attributes FROM");
671
+ expect(query).toContain(
672
+ ") ARRAY JOIN mapKeys(attributes) AS attrKey, mapValues(attributes) AS attrValue",
673
+ );
674
+ expect(query.indexOf("ARRAY JOIN")).toBeGreaterThan(
675
+ query.indexOf("WHERE projectId"),
676
+ );
677
+ expect(query).toContain("GROUP BY attrKey, attrValue");
678
+ });
679
+
680
+ test("maps key/value/count rows and drops keyless ones", async () => {
681
+ stubAndCapture([
682
+ { attrKey: "host.name", attrValue: "web-3", cnt: 30 },
683
+ { attrKey: "", attrValue: "orphan", cnt: 1 },
684
+ ]);
685
+
686
+ const rows: Array<ErrorPatternAttribute> =
687
+ await LogAggregationService.getErrorPatternAttributes(detailRequest());
688
+
689
+ expect(rows).toEqual([{ key: "host.name", value: "web-3", count: 30 }]);
690
+ });
691
+ });
692
+
693
+ describe("getErrorPatternResources", () => {
694
+ test("groups by the resource the log belongs to and keeps its type", async () => {
695
+ const captured: Array<Statement> = stubAndCapture([
696
+ {
697
+ resourceId: "svc-1",
698
+ resourceType: "Host",
699
+ cnt: 21,
700
+ lastSeen: "2026-08-20 22:00:00.000000000",
701
+ },
702
+ ]);
703
+
704
+ const rows: Array<ErrorPatternResource> =
705
+ await LogAggregationService.getErrorPatternResources(detailRequest());
706
+
707
+ expect(captured[0]!.query).toContain("GROUP BY resourceId");
708
+ /*
709
+ * primaryEntityType is Nullable — a row written before the
710
+ * discriminator existed would otherwise surface as a null resource
711
+ * type and break the UI's dispatch to the right detail page.
712
+ */
713
+ expect(captured[0]!.query).toContain(
714
+ "any(ifNull(primaryEntityType, '')) AS resourceType",
715
+ );
716
+
717
+ expect(rows).toEqual([
718
+ {
719
+ resourceId: "svc-1",
720
+ resourceType: "Host",
721
+ count: 21,
722
+ lastSeenAt: "2026-08-20 22:00:00.000000000",
723
+ },
724
+ ]);
725
+ });
726
+ });
727
+
728
+ describe("getErrorPatternTraces", () => {
729
+ test("excludes logs with no trace instead of returning an empty trace id", async () => {
730
+ const captured: Array<Statement> = stubAndCapture([
731
+ {
732
+ traceId: "abc",
733
+ cnt: 3,
734
+ lastSeen: "2026-08-20 22:00:00.000000000",
735
+ resourceId: "svc-1",
736
+ },
737
+ { traceId: "", cnt: 99 },
738
+ ]);
739
+
740
+ const rows: Array<ErrorPatternTrace> =
741
+ await LogAggregationService.getErrorPatternTraces(detailRequest());
742
+
743
+ expect(captured[0]!.query).toContain("AND ifNull(traceId, '') != ''");
744
+ expect(rows).toEqual([
745
+ {
746
+ traceId: "abc",
747
+ count: 3,
748
+ lastSeenAt: "2026-08-20 22:00:00.000000000",
749
+ resourceId: "svc-1",
750
+ },
751
+ ]);
752
+ });
753
+ });
754
+
755
+ describe("getErrorPatternSamples", () => {
756
+ test("returns the newest raw lines with their correlation ids", async () => {
757
+ const captured: Array<Statement> = stubAndCapture([
758
+ {
759
+ _id: "log-1",
760
+ time: "2026-08-20 22:00:00.000000000",
761
+ body: "connection refused to 10.0.0.4:5432",
762
+ severityText: "Error",
763
+ resourceId: "svc-1",
764
+ traceId: "abc",
765
+ spanId: "def",
766
+ },
767
+ ]);
768
+
769
+ const rows: Array<ErrorPatternSample> =
770
+ await LogAggregationService.getErrorPatternSamples(detailRequest());
771
+
772
+ expect(captured[0]!.query).toContain("ORDER BY time DESC");
773
+ expect(rows).toEqual([
774
+ {
775
+ logId: "log-1",
776
+ time: "2026-08-20 22:00:00.000000000",
777
+ body: "connection refused to 10.0.0.4:5432",
778
+ severityText: "Error",
779
+ resourceId: "svc-1",
780
+ traceId: "abc",
781
+ spanId: "def",
782
+ },
783
+ ]);
784
+ });
785
+
786
+ test("a row missing every optional field maps to empty strings, not undefined", async () => {
787
+ stubAndCapture([{}]);
788
+
789
+ const rows: Array<ErrorPatternSample> =
790
+ await LogAggregationService.getErrorPatternSamples(detailRequest());
791
+
792
+ expect(rows).toEqual([
793
+ {
794
+ logId: "",
795
+ time: "",
796
+ body: "",
797
+ severityText: "",
798
+ resourceId: "",
799
+ traceId: "",
800
+ spanId: "",
801
+ },
802
+ ]);
803
+ });
804
+ });