1212from ci_dashboard .api .queries .base import CommonFilters , bucket_expr , rate_pct , to_number
1313
1414COST_STACK_LIMIT = 8
15+ VALID_COST_STACK_GROUPS = frozenset ({"repo" , "author" , "team" })
1516UNMATCHED_RESOURCE_LIMIT = 20
1617UNMATCHED_RESOURCE_MAX_WINDOW_DAYS = 31
1718ENGINEERING_GROUP_NAME = "Engineering Group"
@@ -255,76 +256,85 @@ def _get_engineering_share_by_level_threshold(
255256 )
256257
257258
258- def get_repo_group_cost_stack (engine : Engine , filters : CommonFilters ) -> dict [str , Any ]:
259+ def get_repo_group_cost_stack (
260+ engine : Engine ,
261+ filters : CommonFilters ,
262+ * ,
263+ group_by : str = "repo" ,
264+ ) -> dict [str , Any ]:
265+ if group_by not in VALID_COST_STACK_GROUPS :
266+ group_by = "repo"
267+
259268 with engine .begin () as connection :
260269 where_clause , params = _build_cost_where (filters , table_alias = "c" )
261270 bucket = bucket_expr (connection , "c.usage_date" , filters .granularity )
271+ dimension = _cost_stack_dimension (connection , group_by )
262272 top_rows = connection .execute (
263273 text (
264274 f"""
265275 SELECT
266- COALESCE(NULLIF(c.repo, ''), '(no repo)') AS repo_name ,
276+ { dimension [ "expr" ] } AS dimension_name ,
267277 SUM(c.list_cost) AS list_cost
268- FROM cost_attribution_daily c
278+ FROM { dimension [ "from_clause" ] }
269279 WHERE { where_clause }
270- GROUP BY repo_name
271- ORDER BY list_cost DESC, repo_name
280+ GROUP BY dimension_name
281+ ORDER BY list_cost DESC, dimension_name
272282 LIMIT :limit
273283 """
274284 ),
275- {** params , "limit" : COST_STACK_LIMIT },
285+ {** params , ** dimension [ "params" ], "limit" : COST_STACK_LIMIT },
276286 ).mappings ()
277- top_repos = [str (row ["repo_name " ]) for row in top_rows ]
278- if not top_repos :
287+ top_dimensions = [str (row ["dimension_name" ] or dimension [ "empty_label " ]) for row in top_rows ]
288+ if not top_dimensions :
279289 return {
280290 "series" : [],
281291 "items" : [],
282- "meta" : {** filters .meta (), "limit" : COST_STACK_LIMIT },
292+ "meta" : {** filters .meta (), "limit" : COST_STACK_LIMIT , "group_by" : group_by },
283293 }
284294
285295 dimension_conditions = []
286296 dimension_params : dict [str , Any ] = {}
287- for index , repo_name in enumerate (top_repos ):
288- repo_key = f"repo_ { index } "
297+ for index , dimension_name in enumerate (top_dimensions ):
298+ dimension_key = f"dimension_ { index } "
289299 dimension_conditions .append (
290- f"COALESCE(NULLIF(c.repo, ''), '(no repo)') = :{ repo_key } "
300+ f"{ dimension [ 'expr' ] } = :{ dimension_key } "
291301 )
292- dimension_params [repo_key ] = repo_name
302+ dimension_params [dimension_key ] = dimension_name
293303
294304 rows = connection .execute (
295305 text (
296306 f"""
297307 SELECT
298308 { bucket } AS bucket_start,
299- COALESCE(NULLIF(c.repo, ''), '(no repo)') AS repo_name ,
309+ { dimension [ "expr" ] } AS dimension_name ,
300310 SUM(c.list_cost) AS list_cost
301- FROM cost_attribution_daily c
311+ FROM { dimension [ "from_clause" ] }
302312 WHERE { where_clause }
303313 AND ({ " OR " .join (dimension_conditions )} )
304- GROUP BY bucket_start, repo_name
305- ORDER BY bucket_start, repo_name
314+ GROUP BY bucket_start, dimension_name
315+ ORDER BY bucket_start, dimension_name
306316 """
307317 ),
308- {** params , ** dimension_params },
318+ {** params , ** dimension [ "params" ], ** dimension_params },
309319 ).mappings ()
310320 data_rows = [dict (row ) for row in rows ]
311321
312322 buckets = _bucket_starts (filters , data_rows )
313323 values_by_key = {
314- _repo_key ( repo_name , index ): {bucket : 0.0 for bucket in buckets }
315- for index , repo_name in enumerate (top_repos )
324+ _cost_stack_key ( group_by , dimension_name , index ): {bucket : 0.0 for bucket in buckets }
325+ for index , dimension_name in enumerate (top_dimensions )
316326 }
317327 labels_by_key = {
318- _repo_key ( repo_name , index ): repo_name
319- for index , repo_name in enumerate (top_repos )
328+ _cost_stack_key ( group_by , dimension_name , index ): dimension_name
329+ for index , dimension_name in enumerate (top_dimensions )
320330 }
321- repo_key_by_name = {
322- repo_name : _repo_key ( repo_name , index )
323- for index , repo_name in enumerate (top_repos )
331+ key_by_name = {
332+ dimension_name : _cost_stack_key ( group_by , dimension_name , index )
333+ for index , dimension_name in enumerate (top_dimensions )
324334 }
325335 for row in data_rows :
326- repo_name = str (row ["repo_name " ])
327- key = repo_key_by_name [ repo_name ]
336+ dimension_name = str (row ["dimension_name" ] or dimension [ "empty_label " ])
337+ key = key_by_name [ dimension_name ]
328338 values_by_key [key ][str (row ["bucket_start" ])] = _money (row ["list_cost" ])
329339
330340 return {
@@ -344,7 +354,7 @@ def get_repo_group_cost_stack(engine: Engine, filters: CommonFilters) -> dict[st
344354 }
345355 for key in values_by_key
346356 ],
347- "meta" : {** filters .meta (), "limit" : COST_STACK_LIMIT },
357+ "meta" : {** filters .meta (), "limit" : COST_STACK_LIMIT , "group_by" : group_by },
348358 }
349359
350360
@@ -1157,10 +1167,61 @@ def _null_safe_eq(connection: Connection, left_expr: str, right_expr: str) -> st
11571167 return f"{ left_expr } <=> { right_expr } "
11581168
11591169
1160- def _repo_key (repo_name : str , index : int ) -> str :
1161- if repo_name == "(no repo)" :
1170+ def _cost_stack_dimension (connection : Connection , group_by : str ) -> dict [str , Any ]:
1171+ if group_by not in VALID_COST_STACK_GROUPS :
1172+ group_by = "repo"
1173+
1174+ if group_by == "author" :
1175+ return {
1176+ "expr" : "COALESCE(NULLIF(c.author, ''), '(unknown author)')" ,
1177+ "from_clause" : "cost_attribution_daily c" ,
1178+ "params" : {},
1179+ "empty_label" : "(unknown author)" ,
1180+ }
1181+ if group_by == "team" :
1182+ team_match = _like_prefix_expr (connection , "c_group.path" , "target_group.path" )
1183+ return {
1184+ "expr" : "COALESCE(NULLIF(target_group.name, ''), '(no team)')" ,
1185+ "from_clause" : f"""
1186+ cost_attribution_daily c
1187+ LEFT JOIN roster_groups c_group
1188+ ON c_group.id = c.group_id
1189+ LEFT JOIN (
1190+ SELECT id, path
1191+ FROM roster_groups
1192+ WHERE name = :cost_stack_root_group_name
1193+ AND is_active = 1
1194+ ORDER BY id
1195+ LIMIT 1
1196+ ) root_group
1197+ ON 1=1
1198+ LEFT JOIN roster_groups target_parent
1199+ ON target_parent.is_active = 1
1200+ AND target_parent.parent_id = root_group.id
1201+ LEFT JOIN roster_groups target_group
1202+ ON target_group.is_active = 1
1203+ AND target_group.parent_id = target_parent.id
1204+ AND { team_match }
1205+ """ ,
1206+ "params" : {"cost_stack_root_group_name" : ENGINEERING_GROUP_NAME },
1207+ "empty_label" : "(no team)" ,
1208+ }
1209+ return {
1210+ "expr" : "COALESCE(NULLIF(c.repo, ''), '(no repo)')" ,
1211+ "from_clause" : "cost_attribution_daily c" ,
1212+ "params" : {},
1213+ "empty_label" : "(no repo)" ,
1214+ }
1215+
1216+
1217+ def _cost_stack_key (group_by : str , dimension_name : str , index : int ) -> str :
1218+ if group_by == "repo" and dimension_name == "(no repo)" :
11621219 return "repo__no_repo"
1163- return f"repo__{ index } "
1220+ if group_by == "author" and dimension_name == "(unknown author)" :
1221+ return "author__unknown_author"
1222+ if group_by == "team" and dimension_name == "(no team)" :
1223+ return "team__no_team"
1224+ return f"{ group_by } __{ index } "
11641225
11651226
11661227def _cost_source_value (vendor : str , account_id : str ) -> str :
0 commit comments