fix(ui): use entity key for usage export display - #25153
Conversation
… api_key_breakdown The export utility always extracted team_id from api_key_breakdown metadata to populate the entity label/ID columns. This worked for team exports (where entity key = team_id) but was wrong for every other entity type — tags, orgs, customers, agents, users all showed the API key's team name (e.g. "admins") instead of the actual entity value. Replace extractTeamIdFromApiKeyBreakdown with resolveEntityDisplay which uses the entity key directly. For teams the teamAliasMap still resolves a human-readable alias; for all other types the entity key itself is the correct label.
The previous fix (9dca431) switched the export display logic to use the entity key directly, but left the unit tests asserting the old behavior where id/alias were extracted from api_key_breakdown metadata. Rename mock entity keys from entity1/entity2 to "team-1"/"team-2" to reflect the real shape of team-export payloads (breakdown.entities is keyed by the entity identifier). Replace three tests whose assertions documented the removed behavior: - "should use key alias when available" → entity key is the alias when no team alias map is supplied - "should use team alias map when key alias is not available" → team alias map resolves from the entity key - "should use dash when team id is not available" → entity key itself is the fallback label (illustrated with a tag export)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a bug where entity usage exports (tags, orgs, customers, agents, users) were displaying the team name/ID in the entity column instead of the actual entity value. The root cause was The fix introduces a focused Key changes:
Issue found:
Confidence Score: 5/5Safe to merge — the bug fix is correct and all 83 tests pass; only a vacuous test (P2) warrants a follow-up cleanup. The implementation change is clean and logically sound. The single issue found is a P2 style/test-quality concern: a guarded assertion that can no longer execute after the behavioral change. It does not mask a regression in the production code path; the correct behavior is covered by other new tests. All remaining findings are P2 and do not affect correctness or data integrity. utils.test.ts — the
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/components/EntityUsageExport/utils.ts | Replaces extractTeamIdFromApiKeyBreakdown with the clean resolveEntityDisplay helper that uses the entity key directly as the ID and resolves a human-readable alias via teamAliasMap — correctly fixing leakage of team metadata into non-team exports. |
| ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts | Tests updated to match new semantics with one vacuous test remaining: "should use dash when team alias is not available" has a guarded assertion that can never execute under the new code, effectively removing coverage of that branch without a visible test failure. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Export triggered] --> B[resolveEntities breakdown]
B --> C{breakdown.entities populated?}
C -- Yes --> D[Use breakdown.entities keyed by entity value e.g. team-id, tag-name, customer-id]
C -- No --> E[aggregateApiKeysIntoEntities group api_keys by team_id]
D --> F[resolveEntityDisplay entity, teamAliasMap]
E --> F
F --> G{teamAliasMap has entity key?}
G -- Yes --> H[id = entity key, alias = teamAliasMap lookup e.g. Team One]
G -- No --> I[id = entity key, alias = entity key e.g. my-tag, customer-42]
H --> J[Export row: Entity column = alias, Entity ID column = id]
I --> J
Comments Outside Diff (1)
-
ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts, line 379-386 (link)Vacuous test — inner assertion never executes
After this PR's change,
generateDailyDataalways uses the entity key (or its alias) for the"Team"/"Team ID"columns — it never emits"-". BecausemockSpendDatacontains entities keyed"team-1"and"team-2", the.find((r) => !r["Team ID"] || r["Team ID"] === "-")predicate returnsundefinedon every run, so theexpect(...)inside theifblock is unreachable. The test title implies coverage of a fallback path, but the assertion silently never runs — Vitest reports it as passing because there are zero failed expects.This should either be deleted (the new test at line 388 already documents the correct fallback) or rewritten to assert the actual new behavior:
Rule Used: What: Flag any modifications to existing tests and... (source)
Reviews (1): Last reviewed commit: "test(ui): align EntityUsageExport tests ..." | Re-trigger Greptile
fix(ui): use entity key for usage export display
Summary
team_id/key_aliasfromapi_key_breakdown[firstKey].metadataand using that for the display label and ID of every entity type. For team exports the entity key coincidentally equalledteam_id, so the bug hid there; for all other entity types the team leaked through.extractTeamIdFromApiKeyBreakdownwithresolveEntityDisplay(entity, teamAliasMap)— uses the entity key directly as the ID, and resolves the alias viateamAliasMap(falling back to the entity key for non-team exports).utils.test.tsto match the new semantics: mock entity keys renamedentity1/entity2→"team-1"/"team-2"to mirror real team-export payload shape; three tests whose assertions documented the removed behavior were rewritten.Screenshots
Test plan
npx vitest run src/components/EntityUsageExport/— 83 tests passTagandTag IDcolumns)