@oneuptime/common 10.7.2 → 10.8.1

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 (256) hide show
  1. package/Models/DatabaseModels/CloudResource.ts +846 -0
  2. package/Models/DatabaseModels/CloudResourceInstance.ts +276 -0
  3. package/Models/DatabaseModels/CloudResourceLabelRule.ts +510 -0
  4. package/Models/DatabaseModels/CloudResourceOwnerRule.ts +592 -0
  5. package/Models/DatabaseModels/CloudResourceOwnerTeam.ts +487 -0
  6. package/Models/DatabaseModels/CloudResourceOwnerUser.ts +486 -0
  7. package/Models/DatabaseModels/Host.ts +209 -0
  8. package/Models/DatabaseModels/Index.ts +36 -0
  9. package/Models/DatabaseModels/RumApplication.ts +731 -0
  10. package/Models/DatabaseModels/RumApplicationClient.ts +229 -0
  11. package/Models/DatabaseModels/RumApplicationLabelRule.ts +510 -0
  12. package/Models/DatabaseModels/RumApplicationOwnerRule.ts +592 -0
  13. package/Models/DatabaseModels/RumApplicationOwnerTeam.ts +486 -0
  14. package/Models/DatabaseModels/RumApplicationOwnerUser.ts +485 -0
  15. package/Models/DatabaseModels/ServerlessFunction.ts +881 -0
  16. package/Models/DatabaseModels/ServerlessFunctionInstance.ts +212 -0
  17. package/Models/DatabaseModels/ServerlessFunctionLabelRule.ts +510 -0
  18. package/Models/DatabaseModels/ServerlessFunctionOwnerRule.ts +592 -0
  19. package/Models/DatabaseModels/ServerlessFunctionOwnerTeam.ts +487 -0
  20. package/Models/DatabaseModels/ServerlessFunctionOwnerUser.ts +486 -0
  21. package/Models/DatabaseModels/Service.ts +268 -0
  22. package/Models/DatabaseModels/TelemetryException.ts +15 -1
  23. package/Models/DatabaseModels/WorkflowLog.ts +52 -0
  24. package/Server/API/TelemetryAPI.ts +78 -25
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1780931746908-AddResumeStateToWorkflowLog.ts +21 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1780931863719-AddTelemetryResourceMetadataColumns.ts +108 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1780933132562-AddServerlessFunctionTables.ts +205 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1780935387827-AddCloudResourceTables.ts +195 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1780936579718-AddRumApplicationTables.ts +202 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1780938407319-AddServerlessFunctionRuleTables.ts +156 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1780940721814-AddCloudResourceRuleTables.ts +149 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1780940998002-AddRumApplicationRuleTables.ts +149 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1780941762204-AddTelemetryResourceInventoryTables.ts +95 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1780985763463-AddRumApplicationSdkLanguage.ts +25 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1780987192743-RecastCloudResourcesByEnvironment.ts +30 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +22 -0
  37. package/Server/Infrastructure/Queue.ts +11 -0
  38. package/Server/Services/CloudResourceInstanceService.ts +76 -0
  39. package/Server/Services/CloudResourceLabelRuleEngineService.ts +175 -0
  40. package/Server/Services/CloudResourceLabelRuleService.ts +14 -0
  41. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +192 -0
  42. package/Server/Services/CloudResourceOwnerRuleService.ts +14 -0
  43. package/Server/Services/CloudResourceOwnerTeamService.ts +10 -0
  44. package/Server/Services/CloudResourceOwnerUserService.ts +10 -0
  45. package/Server/Services/CloudResourceService.ts +342 -0
  46. package/Server/Services/ExceptionAggregationService.ts +3 -0
  47. package/Server/Services/HostService.ts +42 -0
  48. package/Server/Services/LogAggregationService.ts +44 -16
  49. package/Server/Services/MetricAggregationService.ts +3 -0
  50. package/Server/Services/OpenTelemetryIngestService.ts +148 -1
  51. package/Server/Services/RumApplicationClientService.ts +69 -0
  52. package/Server/Services/RumApplicationLabelRuleEngineService.ts +175 -0
  53. package/Server/Services/RumApplicationLabelRuleService.ts +14 -0
  54. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +192 -0
  55. package/Server/Services/RumApplicationOwnerRuleService.ts +14 -0
  56. package/Server/Services/RumApplicationOwnerTeamService.ts +10 -0
  57. package/Server/Services/RumApplicationOwnerUserService.ts +10 -0
  58. package/Server/Services/RumApplicationService.ts +301 -0
  59. package/Server/Services/ServerlessFunctionInstanceService.ts +61 -0
  60. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +182 -0
  61. package/Server/Services/ServerlessFunctionLabelRuleService.ts +14 -0
  62. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +199 -0
  63. package/Server/Services/ServerlessFunctionOwnerRuleService.ts +14 -0
  64. package/Server/Services/ServerlessFunctionOwnerTeamService.ts +10 -0
  65. package/Server/Services/ServerlessFunctionOwnerUserService.ts +10 -0
  66. package/Server/Services/ServerlessFunctionService.ts +351 -0
  67. package/Server/Services/ServiceService.ts +95 -8
  68. package/Server/Services/TraceAggregationService.ts +131 -4
  69. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +39 -0
  70. package/Server/Types/Workflow/ComponentCode.ts +9 -0
  71. package/Server/Types/Workflow/Components/Index.ts +2 -0
  72. package/Server/Types/Workflow/Components/Sleep.ts +105 -0
  73. package/Server/Types/Workflow/Workflow.ts +6 -0
  74. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +150 -0
  75. package/Types/Permission.ts +692 -1
  76. package/Types/Telemetry/ServiceType.ts +3 -0
  77. package/Types/Workflow/ComponentID.ts +1 -0
  78. package/Types/Workflow/Components/Sleep.ts +71 -0
  79. package/Types/Workflow/Components.ts +2 -0
  80. package/Types/Workflow/WorkflowStatus.ts +1 -0
  81. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +159 -32
  82. package/UI/Components/Navbar/NavBar.tsx +72 -123
  83. package/UI/Components/Navbar/NavBarMenuModal.tsx +642 -0
  84. package/UI/Components/Workflow/WorkflowStatus.tsx +3 -0
  85. package/build/dist/Models/DatabaseModels/CloudResource.js +871 -0
  86. package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -0
  87. package/build/dist/Models/DatabaseModels/CloudResourceInstance.js +300 -0
  88. package/build/dist/Models/DatabaseModels/CloudResourceInstance.js.map +1 -0
  89. package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js +520 -0
  90. package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js.map +1 -0
  91. package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js +601 -0
  92. package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js.map +1 -0
  93. package/build/dist/Models/DatabaseModels/CloudResourceOwnerTeam.js +503 -0
  94. package/build/dist/Models/DatabaseModels/CloudResourceOwnerTeam.js.map +1 -0
  95. package/build/dist/Models/DatabaseModels/CloudResourceOwnerUser.js +502 -0
  96. package/build/dist/Models/DatabaseModels/CloudResourceOwnerUser.js.map +1 -0
  97. package/build/dist/Models/DatabaseModels/Host.js +215 -0
  98. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  99. package/build/dist/Models/DatabaseModels/Index.js +36 -0
  100. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  101. package/build/dist/Models/DatabaseModels/RumApplication.js +751 -0
  102. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -0
  103. package/build/dist/Models/DatabaseModels/RumApplicationClient.js +252 -0
  104. package/build/dist/Models/DatabaseModels/RumApplicationClient.js.map +1 -0
  105. package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js +520 -0
  106. package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js.map +1 -0
  107. package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js +601 -0
  108. package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js.map +1 -0
  109. package/build/dist/Models/DatabaseModels/RumApplicationOwnerTeam.js +503 -0
  110. package/build/dist/Models/DatabaseModels/RumApplicationOwnerTeam.js.map +1 -0
  111. package/build/dist/Models/DatabaseModels/RumApplicationOwnerUser.js +502 -0
  112. package/build/dist/Models/DatabaseModels/RumApplicationOwnerUser.js.map +1 -0
  113. package/build/dist/Models/DatabaseModels/ServerlessFunction.js +908 -0
  114. package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -0
  115. package/build/dist/Models/DatabaseModels/ServerlessFunctionInstance.js +234 -0
  116. package/build/dist/Models/DatabaseModels/ServerlessFunctionInstance.js.map +1 -0
  117. package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js +520 -0
  118. package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js.map +1 -0
  119. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js +601 -0
  120. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js.map +1 -0
  121. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerTeam.js +503 -0
  122. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerTeam.js.map +1 -0
  123. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerUser.js +502 -0
  124. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerUser.js.map +1 -0
  125. package/build/dist/Models/DatabaseModels/Service.js +276 -0
  126. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  127. package/build/dist/Models/DatabaseModels/TelemetryException.js +12 -1
  128. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  129. package/build/dist/Models/DatabaseModels/WorkflowLog.js +53 -0
  130. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  131. package/build/dist/Server/API/TelemetryAPI.js +61 -23
  132. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  133. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780931746908-AddResumeStateToWorkflowLog.js +14 -0
  134. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780931746908-AddResumeStateToWorkflowLog.js.map +1 -0
  135. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780931863719-AddTelemetryResourceMetadataColumns.js +53 -0
  136. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780931863719-AddTelemetryResourceMetadataColumns.js.map +1 -0
  137. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780933132562-AddServerlessFunctionTables.js +82 -0
  138. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780933132562-AddServerlessFunctionTables.js.map +1 -0
  139. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780935387827-AddCloudResourceTables.js +82 -0
  140. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780935387827-AddCloudResourceTables.js.map +1 -0
  141. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780936579718-AddRumApplicationTables.js +83 -0
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780936579718-AddRumApplicationTables.js.map +1 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780938407319-AddServerlessFunctionRuleTables.js +67 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780938407319-AddServerlessFunctionRuleTables.js.map +1 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780940721814-AddCloudResourceRuleTables.js +60 -0
  146. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780940721814-AddCloudResourceRuleTables.js.map +1 -0
  147. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780940998002-AddRumApplicationRuleTables.js +60 -0
  148. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780940998002-AddRumApplicationRuleTables.js.map +1 -0
  149. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780941762204-AddTelemetryResourceInventoryTables.js +45 -0
  150. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780941762204-AddTelemetryResourceInventoryTables.js.map +1 -0
  151. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780985763463-AddRumApplicationSdkLanguage.js +18 -0
  152. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780985763463-AddRumApplicationSdkLanguage.js.map +1 -0
  153. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780987192743-RecastCloudResourcesByEnvironment.js +27 -0
  154. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780987192743-RecastCloudResourcesByEnvironment.js.map +1 -0
  155. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +22 -0
  156. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  157. package/build/dist/Server/Infrastructure/Queue.js +3 -0
  158. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  159. package/build/dist/Server/Services/CloudResourceInstanceService.js +76 -0
  160. package/build/dist/Server/Services/CloudResourceInstanceService.js.map +1 -0
  161. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +160 -0
  162. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -0
  163. package/build/dist/Server/Services/CloudResourceLabelRuleService.js +13 -0
  164. package/build/dist/Server/Services/CloudResourceLabelRuleService.js.map +1 -0
  165. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +179 -0
  166. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -0
  167. package/build/dist/Server/Services/CloudResourceOwnerRuleService.js +13 -0
  168. package/build/dist/Server/Services/CloudResourceOwnerRuleService.js.map +1 -0
  169. package/build/dist/Server/Services/CloudResourceOwnerTeamService.js +9 -0
  170. package/build/dist/Server/Services/CloudResourceOwnerTeamService.js.map +1 -0
  171. package/build/dist/Server/Services/CloudResourceOwnerUserService.js +9 -0
  172. package/build/dist/Server/Services/CloudResourceOwnerUserService.js.map +1 -0
  173. package/build/dist/Server/Services/CloudResourceService.js +287 -0
  174. package/build/dist/Server/Services/CloudResourceService.js.map +1 -0
  175. package/build/dist/Server/Services/ExceptionAggregationService.js +3 -0
  176. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  177. package/build/dist/Server/Services/HostService.js +29 -1
  178. package/build/dist/Server/Services/HostService.js.map +1 -1
  179. package/build/dist/Server/Services/LogAggregationService.js +36 -10
  180. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  181. package/build/dist/Server/Services/MetricAggregationService.js +3 -0
  182. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  183. package/build/dist/Server/Services/OpenTelemetryIngestService.js +98 -2
  184. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  185. package/build/dist/Server/Services/RumApplicationClientService.js +70 -0
  186. package/build/dist/Server/Services/RumApplicationClientService.js.map +1 -0
  187. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +160 -0
  188. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -0
  189. package/build/dist/Server/Services/RumApplicationLabelRuleService.js +13 -0
  190. package/build/dist/Server/Services/RumApplicationLabelRuleService.js.map +1 -0
  191. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +179 -0
  192. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -0
  193. package/build/dist/Server/Services/RumApplicationOwnerRuleService.js +13 -0
  194. package/build/dist/Server/Services/RumApplicationOwnerRuleService.js.map +1 -0
  195. package/build/dist/Server/Services/RumApplicationOwnerTeamService.js +9 -0
  196. package/build/dist/Server/Services/RumApplicationOwnerTeamService.js.map +1 -0
  197. package/build/dist/Server/Services/RumApplicationOwnerUserService.js +9 -0
  198. package/build/dist/Server/Services/RumApplicationOwnerUserService.js.map +1 -0
  199. package/build/dist/Server/Services/RumApplicationService.js +259 -0
  200. package/build/dist/Server/Services/RumApplicationService.js.map +1 -0
  201. package/build/dist/Server/Services/ServerlessFunctionInstanceService.js +64 -0
  202. package/build/dist/Server/Services/ServerlessFunctionInstanceService.js.map +1 -0
  203. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +160 -0
  204. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -0
  205. package/build/dist/Server/Services/ServerlessFunctionLabelRuleService.js +13 -0
  206. package/build/dist/Server/Services/ServerlessFunctionLabelRuleService.js.map +1 -0
  207. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +179 -0
  208. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -0
  209. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleService.js +13 -0
  210. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleService.js.map +1 -0
  211. package/build/dist/Server/Services/ServerlessFunctionOwnerTeamService.js +9 -0
  212. package/build/dist/Server/Services/ServerlessFunctionOwnerTeamService.js.map +1 -0
  213. package/build/dist/Server/Services/ServerlessFunctionOwnerUserService.js +9 -0
  214. package/build/dist/Server/Services/ServerlessFunctionOwnerUserService.js.map +1 -0
  215. package/build/dist/Server/Services/ServerlessFunctionService.js +299 -0
  216. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -0
  217. package/build/dist/Server/Services/ServiceService.js +63 -7
  218. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  219. package/build/dist/Server/Services/TraceAggregationService.js +108 -4
  220. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  221. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +39 -0
  222. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  223. package/build/dist/Server/Types/Workflow/ComponentCode.js.map +1 -1
  224. package/build/dist/Server/Types/Workflow/Components/Index.js +2 -0
  225. package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
  226. package/build/dist/Server/Types/Workflow/Components/Sleep.js +85 -0
  227. package/build/dist/Server/Types/Workflow/Components/Sleep.js.map +1 -0
  228. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +90 -0
  229. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  230. package/build/dist/Types/Permission.js +609 -1
  231. package/build/dist/Types/Permission.js.map +1 -1
  232. package/build/dist/Types/Telemetry/ServiceType.js +3 -0
  233. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  234. package/build/dist/Types/Workflow/ComponentID.js +1 -0
  235. package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
  236. package/build/dist/Types/Workflow/Components/Sleep.js +64 -0
  237. package/build/dist/Types/Workflow/Components/Sleep.js.map +1 -0
  238. package/build/dist/Types/Workflow/Components.js +2 -0
  239. package/build/dist/Types/Workflow/Components.js.map +1 -1
  240. package/build/dist/Types/Workflow/WorkflowStatus.js +1 -0
  241. package/build/dist/Types/Workflow/WorkflowStatus.js.map +1 -1
  242. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +113 -19
  243. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  244. package/build/dist/UI/Components/Navbar/NavBar.js +34 -66
  245. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  246. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +412 -0
  247. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -0
  248. package/build/dist/UI/Components/Workflow/WorkflowStatus.js +3 -0
  249. package/build/dist/UI/Components/Workflow/WorkflowStatus.js.map +1 -1
  250. package/package.json +1 -1
  251. package/UI/Components/Navbar/NavBarMenu.tsx +0 -183
  252. package/UI/Components/Navbar/NavBarMenuItem.tsx +0 -146
  253. package/build/dist/UI/Components/Navbar/NavBarMenu.js +0 -82
  254. package/build/dist/UI/Components/Navbar/NavBarMenu.js.map +0 -1
  255. package/build/dist/UI/Components/Navbar/NavBarMenuItem.js +0 -109
  256. package/build/dist/UI/Components/Navbar/NavBarMenuItem.js.map +0 -1
@@ -119,32 +119,119 @@ export class Service extends DatabaseService<Model> {
119
119
  * per batch instead of a DB write.
120
120
  */
121
121
  @CaptureSpan()
122
- public async updateLastSeen(serviceId: ObjectID): Promise<void> {
122
+ public async updateLastSeen(
123
+ serviceId: ObjectID,
124
+ extra?: {
125
+ serviceVersion?: string | undefined;
126
+ deploymentEnvironment?: string | undefined;
127
+ serviceNamespace?: string | undefined;
128
+ runtimeName?: string | undefined;
129
+ runtimeVersion?: string | undefined;
130
+ cloudProvider?: string | undefined;
131
+ cloudPlatform?: string | undefined;
132
+ cloudRegion?: string | undefined;
133
+ cloudAccountId?: string | undefined;
134
+ },
135
+ ): Promise<void> {
136
+ /*
137
+ * Throttle keyed on a fingerprint of the metadata so the steady-state
138
+ * firehose (the same serviceId re-resolved every batch) costs one
139
+ * in-memory cache lookup, but a changed attribute (e.g. a new
140
+ * service.version after a deploy) busts the cache and writes
141
+ * immediately. With no extras the fingerprint is constant, preserving
142
+ * the original "refresh lastSeenAt at most once per window" behaviour.
143
+ */
123
144
  const cacheKey: string = serviceId.toString();
145
+ const fingerprint: string = this.fingerprintLastSeenExtras(extra);
124
146
  const cached: string | null = await GlobalCache.getString(
125
147
  LAST_SEEN_CACHE_NAMESPACE,
126
148
  cacheKey,
127
149
  );
128
150
 
129
- if (cached) {
151
+ if (cached === fingerprint) {
130
152
  return;
131
153
  }
132
154
 
133
- await GlobalCache.setString(LAST_SEEN_CACHE_NAMESPACE, cacheKey, "1", {
134
- expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS,
135
- });
155
+ await GlobalCache.setString(
156
+ LAST_SEEN_CACHE_NAMESPACE,
157
+ cacheKey,
158
+ fingerprint,
159
+ {
160
+ expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS,
161
+ },
162
+ );
163
+
164
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
+ const data: any = {
166
+ lastSeenAt: OneUptimeDate.getCurrentDate(),
167
+ };
168
+
169
+ if (extra?.serviceVersion) {
170
+ data.serviceVersion = extra.serviceVersion;
171
+ }
172
+ if (extra?.deploymentEnvironment) {
173
+ data.deploymentEnvironment = extra.deploymentEnvironment;
174
+ }
175
+ if (extra?.serviceNamespace) {
176
+ data.serviceNamespace = extra.serviceNamespace;
177
+ }
178
+ if (extra?.runtimeName) {
179
+ data.runtimeName = extra.runtimeName;
180
+ }
181
+ if (extra?.runtimeVersion) {
182
+ data.runtimeVersion = extra.runtimeVersion;
183
+ }
184
+ if (extra?.cloudProvider) {
185
+ data.cloudProvider = extra.cloudProvider;
186
+ }
187
+ if (extra?.cloudPlatform) {
188
+ data.cloudPlatform = extra.cloudPlatform;
189
+ }
190
+ if (extra?.cloudRegion) {
191
+ data.cloudRegion = extra.cloudRegion;
192
+ }
193
+ if (extra?.cloudAccountId) {
194
+ data.cloudAccountId = extra.cloudAccountId;
195
+ }
136
196
 
137
197
  await this.updateOneById({
138
198
  id: serviceId,
139
- data: {
140
- lastSeenAt: OneUptimeDate.getCurrentDate(),
141
- },
199
+ data: data,
142
200
  props: {
143
201
  isRoot: true,
144
202
  },
145
203
  });
146
204
  }
147
205
 
206
+ private fingerprintLastSeenExtras(extra?: {
207
+ serviceVersion?: string | undefined;
208
+ deploymentEnvironment?: string | undefined;
209
+ serviceNamespace?: string | undefined;
210
+ runtimeName?: string | undefined;
211
+ runtimeVersion?: string | undefined;
212
+ cloudProvider?: string | undefined;
213
+ cloudPlatform?: string | undefined;
214
+ cloudRegion?: string | undefined;
215
+ cloudAccountId?: string | undefined;
216
+ }): string {
217
+ const normalized: Record<string, string | null> = {
218
+ serviceVersion: extra?.serviceVersion ?? null,
219
+ deploymentEnvironment: extra?.deploymentEnvironment ?? null,
220
+ serviceNamespace: extra?.serviceNamespace ?? null,
221
+ runtimeName: extra?.runtimeName ?? null,
222
+ runtimeVersion: extra?.runtimeVersion ?? null,
223
+ cloudProvider: extra?.cloudProvider ?? null,
224
+ cloudPlatform: extra?.cloudPlatform ?? null,
225
+ cloudRegion: extra?.cloudRegion ?? null,
226
+ cloudAccountId: extra?.cloudAccountId ?? null,
227
+ };
228
+
229
+ return crypto
230
+ .createHash("sha1")
231
+ .update(JSON.stringify(normalized))
232
+ .digest("hex");
233
+ }
234
+
148
235
  /**
149
236
  * Additively attach labels to a telemetry service. Existing labels
150
237
  * are never removed — manual labels set via the UI survive ingest.
@@ -81,6 +81,9 @@ export class TraceAggregationService {
81
81
  ["hostId", ServiceType.Host],
82
82
  ["dockerHostId", ServiceType.DockerHost],
83
83
  ["kubernetesClusterId", ServiceType.KubernetesCluster],
84
+ ["serverlessFunctionId", ServiceType.ServerlessFunction],
85
+ ["cloudResourceId", ServiceType.CloudResource],
86
+ ["rumApplicationId", ServiceType.RealUserMonitor],
84
87
  ]);
85
88
  private static readonly ATTRIBUTE_KEY_PATTERN: RegExp = /^[a-zA-Z0-9._:/-]+$/;
86
89
  private static readonly MAX_FACET_KEY_LENGTH: number = 256;
@@ -342,6 +345,121 @@ export class TraceAggregationService {
342
345
  return result;
343
346
  }
344
347
 
348
+ /*
349
+ * Accurate per-service and per-status counts over the FULL time window,
350
+ * computed with a real GROUP BY instead of the recent-N sample in
351
+ * getFacetValuesFromSample(). The sample saturates with whichever service
352
+ * is chattiest right now, so high-volume services that aren't in the most
353
+ * recent N root spans read 0 — the "top 1000" symptom. This GROUP BY is
354
+ * exact regardless of skew.
355
+ *
356
+ * It is cheap because it rides the proj_hist_by_minute aggregate projection
357
+ * (projectId, minute, serviceId, statusCode, isRootSpan -> count): a 1-month
358
+ * window reads a few thousand pre-aggregated minute rows in single-digit ms
359
+ * instead of scanning tens of millions of raw spans. Two things are required
360
+ * for ClickHouse to actually pick that projection, both load-bearing:
361
+ * 1. The time predicate must be on toStartOfMinute(startTime) — the
362
+ * projection's key expression — NOT raw startTime. A raw startTime
363
+ * filter references a column the aggregate projection does not store, so
364
+ * ClickHouse rejects the projection and full-scans. (Window edges land
365
+ * on minute boundaries, consistent with the minute-bucketed histogram.)
366
+ * 2. Every other predicate must be on a projection column. isRootSpan,
367
+ * serviceId and statusCode all are, so the default sidebar load and
368
+ * drill-down-by-service stay on the projection. A non-projection filter
369
+ * (kind / name / traceId / attributes) transparently falls back to a
370
+ * base-table scan — still correct, still bounded by max_execution_time.
371
+ *
372
+ * serviceId is intentionally NOT disambiguated by serviceType here. Resource
373
+ * IDs are globally unique, so a single serviceId -> count map correctly
374
+ * serves the service / host / docker host / k8s cluster facets once merged
375
+ * against each Postgres source-of-truth list (a host id never collides with
376
+ * a service id, so an unrelated entry is simply never looked up). Omitting
377
+ * the serviceType predicate keeps the query projection-eligible.
378
+ */
379
+ @CaptureSpan()
380
+ public static async getResourceFacetCounts(
381
+ request: MultiFacetRequest,
382
+ ): Promise<{
383
+ serviceCounts: Map<string, number>;
384
+ statusCounts: Map<string, number>;
385
+ }> {
386
+ const statement: Statement = new Statement();
387
+ statement.append(
388
+ `SELECT serviceId, statusCode, count() AS cnt FROM ${TraceAggregationService.TABLE_NAME}`,
389
+ );
390
+ statement.append(
391
+ SQL` WHERE projectId = ${{
392
+ type: TableColumnType.ObjectID,
393
+ value: request.projectId,
394
+ }} AND toStartOfMinute(startTime) >= toStartOfMinute(${{
395
+ type: TableColumnType.Date,
396
+ value: request.startTime,
397
+ }}) AND toStartOfMinute(startTime) <= toStartOfMinute(${{
398
+ type: TableColumnType.Date,
399
+ value: request.endTime,
400
+ }})`,
401
+ );
402
+
403
+ TraceAggregationService.appendCommonFilters(statement, request);
404
+
405
+ statement.append(" GROUP BY serviceId, statusCode");
406
+
407
+ /*
408
+ * Cap runtime below nginx's 60s proxy_read_timeout and explicitly allow
409
+ * projection use so proj_hist_by_minute is read when eligible (see the
410
+ * toStartOfMinute note above).
411
+ */
412
+ statement.append(
413
+ " SETTINGS max_execution_time = 45, timeout_overflow_mode = 'break', optimize_use_projections = 1",
414
+ );
415
+
416
+ const serviceCounts: Map<string, number> = new Map<string, number>();
417
+ const statusCounts: Map<string, number> = new Map<string, number>();
418
+
419
+ const dbResult: Results = await SpanService.executeQuery(statement);
420
+
421
+ let rows: Array<JSONObject> = [];
422
+ try {
423
+ const response: DbJSONResponse = await dbResult.json<{
424
+ data?: Array<JSONObject>;
425
+ }>();
426
+ rows = response.data || [];
427
+ } catch {
428
+ /*
429
+ * 'break' mode can return truncated JSON on timeout. Degrade to empty
430
+ * counts — the Postgres resolver still lists every resource (count 0),
431
+ * which is no worse than the prior transient-failure behavior.
432
+ */
433
+ logger.warn(
434
+ "Resource facet count query returned unparseable response, returning empty counts",
435
+ );
436
+ return { serviceCounts, statusCounts };
437
+ }
438
+
439
+ for (const row of rows) {
440
+ const cnt: number = Number(row["cnt"] || 0);
441
+
442
+ const rawServiceId: unknown = row["serviceId"];
443
+ if (rawServiceId !== undefined && rawServiceId !== null) {
444
+ const serviceId: string = String(rawServiceId);
445
+ if (serviceId.length > 0) {
446
+ serviceCounts.set(
447
+ serviceId,
448
+ (serviceCounts.get(serviceId) || 0) + cnt,
449
+ );
450
+ }
451
+ }
452
+
453
+ const rawStatusCode: unknown = row["statusCode"];
454
+ if (rawStatusCode !== undefined && rawStatusCode !== null) {
455
+ const statusCode: string = String(rawStatusCode);
456
+ statusCounts.set(statusCode, (statusCounts.get(statusCode) || 0) + cnt);
457
+ }
458
+ }
459
+
460
+ return { serviceCounts, statusCounts };
461
+ }
462
+
345
463
  private static mapStatusCodeToSeries(code: number): string {
346
464
  if (code === 1) {
347
465
  return "ok";
@@ -363,6 +481,15 @@ export class TraceAggregationService {
363
481
  * even for multi-week ranges. The outer query then re-buckets the tiny
364
482
  * minute-level result to the requested bucket size.
365
483
  *
484
+ * The time window is filtered on toStartOfMinute(startTime) — the
485
+ * projection's key expression — NOT raw startTime. A raw startTime
486
+ * predicate references a column the aggregate projection does not store,
487
+ * so ClickHouse rejects proj_hist_by_minute and full-scans the base table
488
+ * (verified: 32M rows / ~220ms vs 1.5K rows / ~6ms with this form). The
489
+ * window edges round to the minute, which is consistent with the
490
+ * minute-bucketed output and only shifts the first/last bucket by the
491
+ * partial boundary minute when the range is not minute-aligned.
492
+ *
366
493
  * If any non-projection filter (kind, name, traceId, nameSearchText,
367
494
  * attributes) is active, ClickHouse transparently falls back to
368
495
  * scanning the main table for the inner query — same cost as before.
@@ -385,14 +512,14 @@ export class TraceAggregationService {
385
512
  type: TableColumnType.ObjectID,
386
513
  value: request.projectId,
387
514
  }}
388
- AND startTime >= ${{
515
+ AND toStartOfMinute(startTime) >= toStartOfMinute(${{
389
516
  type: TableColumnType.Date,
390
517
  value: request.startTime,
391
- }}
392
- AND startTime <= ${{
518
+ }})
519
+ AND toStartOfMinute(startTime) <= toStartOfMinute(${{
393
520
  type: TableColumnType.Date,
394
521
  value: request.endTime,
395
- }}
522
+ }})
396
523
  `;
397
524
 
398
525
  TraceAggregationService.appendCommonFilters(statement, request);
@@ -20,6 +20,12 @@ import DockerHostOwnerTeamService from "../../../Services/DockerHostOwnerTeamSer
20
20
  import DockerHostOwnerUserService from "../../../Services/DockerHostOwnerUserService";
21
21
  import KubernetesClusterOwnerTeamService from "../../../Services/KubernetesClusterOwnerTeamService";
22
22
  import KubernetesClusterOwnerUserService from "../../../Services/KubernetesClusterOwnerUserService";
23
+ import ServerlessFunctionOwnerTeamService from "../../../Services/ServerlessFunctionOwnerTeamService";
24
+ import ServerlessFunctionOwnerUserService from "../../../Services/ServerlessFunctionOwnerUserService";
25
+ import CloudResourceOwnerTeamService from "../../../Services/CloudResourceOwnerTeamService";
26
+ import CloudResourceOwnerUserService from "../../../Services/CloudResourceOwnerUserService";
27
+ import RumApplicationOwnerTeamService from "../../../Services/RumApplicationOwnerTeamService";
28
+ import RumApplicationOwnerUserService from "../../../Services/RumApplicationOwnerUserService";
23
29
  import StatusPageOwnerTeamService from "../../../Services/StatusPageOwnerTeamService";
24
30
  import StatusPageOwnerUserService from "../../../Services/StatusPageOwnerUserService";
25
31
  import WorkflowOwnerTeamService from "../../../Services/WorkflowOwnerTeamService";
@@ -35,6 +41,9 @@ import MonitorService from "../../../Services/MonitorService";
35
41
  import HostService from "../../../Services/HostService";
36
42
  import DockerHostService from "../../../Services/DockerHostService";
37
43
  import KubernetesClusterService from "../../../Services/KubernetesClusterService";
44
+ import ServerlessFunctionService from "../../../Services/ServerlessFunctionService";
45
+ import CloudResourceService from "../../../Services/CloudResourceService";
46
+ import RumApplicationService from "../../../Services/RumApplicationService";
38
47
 
39
48
  /*
40
49
  * Maps an operational model name (e.g. "Monitor") to the two services that
@@ -180,6 +189,36 @@ const ownerTableRegistry: Map<string, OwnerTablePair> = new Map<
180
189
  modelService: KubernetesClusterService,
181
190
  },
182
191
  ],
192
+ [
193
+ "ServerlessFunction",
194
+ {
195
+ ownerUserService: ServerlessFunctionOwnerUserService,
196
+ ownerTeamService: ServerlessFunctionOwnerTeamService,
197
+ fkColumn: "serverlessFunctionId",
198
+ canOwnTelemetry: true,
199
+ modelService: ServerlessFunctionService,
200
+ },
201
+ ],
202
+ [
203
+ "CloudResource",
204
+ {
205
+ ownerUserService: CloudResourceOwnerUserService,
206
+ ownerTeamService: CloudResourceOwnerTeamService,
207
+ fkColumn: "cloudResourceId",
208
+ canOwnTelemetry: true,
209
+ modelService: CloudResourceService,
210
+ },
211
+ ],
212
+ [
213
+ "RumApplication",
214
+ {
215
+ ownerUserService: RumApplicationOwnerUserService,
216
+ ownerTeamService: RumApplicationOwnerTeamService,
217
+ fkColumn: "rumApplicationId",
218
+ canOwnTelemetry: true,
219
+ modelService: RumApplicationService,
220
+ },
221
+ ],
183
222
  [
184
223
  "Workflow",
185
224
  {
@@ -38,6 +38,15 @@ export interface RunOptions {
38
38
  export interface RunReturnType {
39
39
  returnValues: JSONObject;
40
40
  executePort?: Port | undefined;
41
+ /**
42
+ * When set to a positive number of milliseconds, the workflow runner will
43
+ * suspend execution AFTER this component (the components connected to
44
+ * `executePort` are scheduled but not run inline). The run is persisted and
45
+ * a delayed job re-enqueues it once the duration elapses, at which point it
46
+ * resumes from where it left off. Used by the Sleep component to implement a
47
+ * durable delay that does not block a worker.
48
+ */
49
+ suspendForMs?: number | undefined;
41
50
  }
42
51
 
43
52
  export default class ComponentCode {
@@ -28,6 +28,7 @@ import ManualTrigger from "./Manual";
28
28
  import MicrosoftTeamsSendMessageToChannel from "./MicrosoftTeams/SendMessageToChannel";
29
29
  import Schedule from "./Schedule";
30
30
  import SlackSendMessageToChannel from "./Slack/SendMessageToChannel";
31
+ import Sleep from "./Sleep";
31
32
  import TelegramSendMessageToChat from "./Telegram/SendMessageToChat";
32
33
  import WebhookTrigger from "./Webhook";
33
34
  import ExecuteWorkflow from "./Workflow";
@@ -59,6 +60,7 @@ const Components: Dictionary<ComponentCode> = {
59
60
  [ComponentID.SendEmail]: new Email(),
60
61
  [ComponentID.IfElse]: new IfElse(),
61
62
  [ComponentID.WorkflowRun]: new ExecuteWorkflow(),
63
+ [ComponentID.Sleep]: new Sleep(),
62
64
  };
63
65
 
64
66
  for (const baseModelService of Services) {
@@ -0,0 +1,105 @@
1
+ import ComponentCode, { RunOptions, RunReturnType } from "../ComponentCode";
2
+ import BadDataException from "../../../../Types/Exception/BadDataException";
3
+ import { JSONObject } from "../../../../Types/JSON";
4
+ import ComponentMetadata, { Port } from "../../../../Types/Workflow/Component";
5
+ import ComponentID from "../../../../Types/Workflow/ComponentID";
6
+ import SleepComponents from "../../../../Types/Workflow/Components/Sleep";
7
+ import CaptureSpan from "../../../Utils/Telemetry/CaptureSpan";
8
+
9
+ /**
10
+ * Maximum duration a single Sleep component may suspend for. Bounds how far in
11
+ * the future a delayed resume job can be parked.
12
+ */
13
+ export const MAX_SLEEP_IN_MS: number = 30 * 24 * 60 * 60 * 1000; // 30 days
14
+
15
+ export default class Sleep extends ComponentCode {
16
+ public constructor() {
17
+ super();
18
+
19
+ const SleepComponent: ComponentMetadata | undefined = SleepComponents.find(
20
+ (i: ComponentMetadata) => {
21
+ return i.id === ComponentID.Sleep;
22
+ },
23
+ );
24
+
25
+ if (!SleepComponent) {
26
+ throw new BadDataException("Component not found.");
27
+ }
28
+
29
+ this.setMetadata(SleepComponent);
30
+ }
31
+
32
+ /**
33
+ * Coerce a workflow argument (which may arrive as a string from the form, a
34
+ * number, or null) into a non-negative integer. Invalid / negative values
35
+ * are treated as 0.
36
+ */
37
+ private toNonNegativeNumber(value: unknown): number {
38
+ const parsed: number =
39
+ typeof value === "number" ? value : parseFloat(value as string);
40
+
41
+ if (isNaN(parsed) || !isFinite(parsed) || parsed < 0) {
42
+ return 0;
43
+ }
44
+
45
+ return parsed;
46
+ }
47
+
48
+ @CaptureSpan()
49
+ public override async run(
50
+ args: JSONObject,
51
+ options: RunOptions,
52
+ ): Promise<RunReturnType> {
53
+ const outPort: Port | undefined = this.getMetadata().outPorts.find(
54
+ (p: Port) => {
55
+ return p.id === "out";
56
+ },
57
+ );
58
+
59
+ if (!outPort) {
60
+ throw options.onError(new BadDataException("Out port not found"));
61
+ }
62
+
63
+ const days: number = this.toNonNegativeNumber(args["days"]);
64
+ const hours: number = this.toNonNegativeNumber(args["hours"]);
65
+ const minutes: number = this.toNonNegativeNumber(args["minutes"]);
66
+ const seconds: number = this.toNonNegativeNumber(args["seconds"]);
67
+
68
+ let sleepForMs: number =
69
+ days * 24 * 60 * 60 * 1000 +
70
+ hours * 60 * 60 * 1000 +
71
+ minutes * 60 * 1000 +
72
+ seconds * 1000;
73
+
74
+ sleepForMs = Math.round(sleepForMs);
75
+
76
+ if (sleepForMs > MAX_SLEEP_IN_MS) {
77
+ options.log(
78
+ `Requested sleep of ${sleepForMs}ms exceeds the maximum of ${MAX_SLEEP_IN_MS}ms. Clamping to the maximum.`,
79
+ );
80
+ sleepForMs = MAX_SLEEP_IN_MS;
81
+ }
82
+
83
+ if (sleepForMs <= 0) {
84
+ // Nothing to sleep for — behave as a pass-through.
85
+ options.log(
86
+ "Sleep duration is zero. Continuing to the next step immediately.",
87
+ );
88
+
89
+ return Promise.resolve({
90
+ returnValues: {},
91
+ executePort: outPort,
92
+ });
93
+ }
94
+
95
+ options.log(
96
+ `Workflow will sleep for ${sleepForMs}ms and then continue to the next step.`,
97
+ );
98
+
99
+ return Promise.resolve({
100
+ returnValues: {},
101
+ executePort: outPort,
102
+ suspendForMs: sleepForMs,
103
+ });
104
+ }
105
+ }
@@ -6,6 +6,12 @@ export interface RunProps {
6
6
  workflowId: ObjectID;
7
7
  workflowLogId: ObjectID | null;
8
8
  timeout: number;
9
+ /**
10
+ * True when this run is resuming a previously-suspended workflow (e.g. after
11
+ * a Sleep step). The runner rehydrates execution state from the WorkflowLog's
12
+ * `resumeData` instead of starting from the trigger.
13
+ */
14
+ isResume?: boolean;
9
15
  /**
10
16
  * Chain of ancestor workflow IDs that led to this run, oldest first.
11
17
  * Empty / undefined for top-level runs. Used by the Execute Workflow
@@ -6,10 +6,16 @@ import ServiceModel from "../../../Models/DatabaseModels/Service";
6
6
  import HostModel from "../../../Models/DatabaseModels/Host";
7
7
  import DockerHostModel from "../../../Models/DatabaseModels/DockerHost";
8
8
  import KubernetesClusterModel from "../../../Models/DatabaseModels/KubernetesCluster";
9
+ import ServerlessFunctionModel from "../../../Models/DatabaseModels/ServerlessFunction";
10
+ import CloudResourceModel from "../../../Models/DatabaseModels/CloudResource";
11
+ import RumApplicationModel from "../../../Models/DatabaseModels/RumApplication";
9
12
  import ServiceService from "../../Services/ServiceService";
10
13
  import HostService from "../../Services/HostService";
11
14
  import DockerHostService from "../../Services/DockerHostService";
12
15
  import KubernetesClusterService from "../../Services/KubernetesClusterService";
16
+ import ServerlessFunctionService from "../../Services/ServerlessFunctionService";
17
+ import CloudResourceService from "../../Services/CloudResourceService";
18
+ import RumApplicationService from "../../Services/RumApplicationService";
13
19
  import CaptureSpan from "./CaptureSpan";
14
20
 
15
21
  /*
@@ -25,6 +31,9 @@ export const RESOURCE_FACET_KEYS: ReadonlySet<string> = new Set([
25
31
  "hostId",
26
32
  "dockerHostId",
27
33
  "kubernetesClusterId",
34
+ "serverlessFunctionId",
35
+ "cloudResourceId",
36
+ "rumApplicationId",
28
37
  ]);
29
38
 
30
39
  export interface ResourceFacetSpec {
@@ -111,6 +120,27 @@ export default class ResourceFacetResolver {
111
120
  searchText,
112
121
  limit,
113
122
  );
123
+ case "serverlessFunctionId":
124
+ return ResourceFacetResolver.queryServerlessFunctions(
125
+ projectId,
126
+ spec.counts,
127
+ searchText,
128
+ limit,
129
+ );
130
+ case "cloudResourceId":
131
+ return ResourceFacetResolver.queryCloudResources(
132
+ projectId,
133
+ spec.counts,
134
+ searchText,
135
+ limit,
136
+ );
137
+ case "rumApplicationId":
138
+ return ResourceFacetResolver.queryRumApplications(
139
+ projectId,
140
+ spec.counts,
141
+ searchText,
142
+ limit,
143
+ );
114
144
  default:
115
145
  return [];
116
146
  }
@@ -265,6 +295,126 @@ export default class ResourceFacetResolver {
265
295
  );
266
296
  }
267
297
 
298
+ private static async queryServerlessFunctions(
299
+ projectId: ObjectID,
300
+ counts: Map<string, number>,
301
+ searchText: string | undefined,
302
+ limit: number,
303
+ ): Promise<Array<ResolvedFacetValue>> {
304
+ const query: Record<string, unknown> = { projectId };
305
+ if (searchText) {
306
+ query["name"] = new MultiSearch({
307
+ fields: ["name", "functionIdentifier"],
308
+ value: searchText,
309
+ });
310
+ }
311
+
312
+ const functions: Array<ServerlessFunctionModel> =
313
+ await ServerlessFunctionService.findBy({
314
+ query: query as any,
315
+ select: {
316
+ _id: true,
317
+ name: true,
318
+ functionIdentifier: true,
319
+ },
320
+ limit: new PositiveNumber(limit),
321
+ skip: new PositiveNumber(0),
322
+ props: { isRoot: true },
323
+ });
324
+
325
+ return ResourceFacetResolver.mergeCounts(
326
+ functions.map(
327
+ (f: ServerlessFunctionModel): { id: string; displayName: string } => {
328
+ return {
329
+ id: f._id ? f._id.toString() : "",
330
+ displayName: f.name || f.functionIdentifier || "Unknown",
331
+ };
332
+ },
333
+ ),
334
+ counts,
335
+ );
336
+ }
337
+
338
+ private static async queryCloudResources(
339
+ projectId: ObjectID,
340
+ counts: Map<string, number>,
341
+ searchText: string | undefined,
342
+ limit: number,
343
+ ): Promise<Array<ResolvedFacetValue>> {
344
+ const query: Record<string, unknown> = { projectId };
345
+ if (searchText) {
346
+ query["name"] = new MultiSearch({
347
+ fields: ["name", "resourceIdentifier"],
348
+ value: searchText,
349
+ });
350
+ }
351
+
352
+ const resources: Array<CloudResourceModel> =
353
+ await CloudResourceService.findBy({
354
+ query: query as any,
355
+ select: {
356
+ _id: true,
357
+ name: true,
358
+ resourceIdentifier: true,
359
+ },
360
+ limit: new PositiveNumber(limit),
361
+ skip: new PositiveNumber(0),
362
+ props: { isRoot: true },
363
+ });
364
+
365
+ return ResourceFacetResolver.mergeCounts(
366
+ resources.map(
367
+ (r: CloudResourceModel): { id: string; displayName: string } => {
368
+ return {
369
+ id: r._id ? r._id.toString() : "",
370
+ displayName: r.name || r.resourceIdentifier || "Unknown",
371
+ };
372
+ },
373
+ ),
374
+ counts,
375
+ );
376
+ }
377
+
378
+ private static async queryRumApplications(
379
+ projectId: ObjectID,
380
+ counts: Map<string, number>,
381
+ searchText: string | undefined,
382
+ limit: number,
383
+ ): Promise<Array<ResolvedFacetValue>> {
384
+ const query: Record<string, unknown> = { projectId };
385
+ if (searchText) {
386
+ query["name"] = new MultiSearch({
387
+ fields: ["name", "appIdentifier"],
388
+ value: searchText,
389
+ });
390
+ }
391
+
392
+ const apps: Array<RumApplicationModel> =
393
+ await RumApplicationService.findBy({
394
+ query: query as any,
395
+ select: {
396
+ _id: true,
397
+ name: true,
398
+ appIdentifier: true,
399
+ },
400
+ limit: new PositiveNumber(limit),
401
+ skip: new PositiveNumber(0),
402
+ props: { isRoot: true },
403
+ });
404
+
405
+ return ResourceFacetResolver.mergeCounts(
406
+ apps.map(
407
+ (a: RumApplicationModel): { id: string; displayName: string } => {
408
+ return {
409
+ id: a._id ? a._id.toString() : "",
410
+ displayName: a.name || a.appIdentifier || "Unknown",
411
+ };
412
+ },
413
+ ),
414
+ counts,
415
+ );
416
+ }
417
+
268
418
  /*
269
419
  * Combine Postgres-sourced entities with counts from the ClickHouse sample.
270
420
  * Entities without a count default to 0 (they exist in the project but