fix(teams): expose keys_count on /v2/team/list and wire UI Resources badge#28502
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR fixes the
Confidence Score: 5/5Safe to merge — the change is purely additive on the backend and fully backwards-compatible in the UI. The batched group_by query follows the established pattern in spend_management_endpoints.py, the empty-page and deleted-table short-circuits are correctly guarded, and all three UI display sites are updated consistently. The keys.length fallback preserves compatibility with older API responses. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/management_endpoints/team_endpoints.py | Adds a single group_by query on LiteLLM_VerificationToken to aggregate per-team key counts for the current page; result is passed into _convert_teams_to_response_models which threads it into TeamListItem.keys_count. Logic is sound — empty-page and deleted-table branches correctly skip the DB call. |
| litellm/types/proxy/management_endpoints/team_endpoints.py | Adds keys_count: int = 0 to TeamListItem with a safe default — additive, backwards-compatible schema change. |
| tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py | Adds 3 new unit tests (happy path, empty page, deleted-status) and stubs group_by on 4 existing tests that would otherwise break. New mocks correctly match the actual group_by call signature and return format. |
| ui/litellm-dashboard/src/components/OldTeams.tsx | Reads keys_count (with keys.length fallback) for the Resources column badge, the delete-modal warning banner, and the resource-information row. Logic covers all three display sites consistently. |
| ui/litellm-dashboard/src/app/(dashboard)/teams/components/TeamsTable/TeamsTable.tsx | Replaces the keys.length chain with keys_count from PerTeamInfo; ?? 0 fallback correctly handles undefined and falsy-but-valid 0 counts. |
| ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx | Adds keys_count?: number as an optional field to the Team interface — non-breaking addition. |
| ui/litellm-dashboard/src/components/OldTeams.test.tsx | Adds 2 render tests asserting the cyan Keys badge displays keys_count from the v2 payload and falls back to keys.length when absent. |
Reviews (2): Last reviewed commit: "fix(teams ui): add keys_count to TeamsTa..." | Re-trigger Greptile
| # GROUP BY. The IN clause is bounded by page_size and uses the existing | ||
| # @@index([team_id]) on LiteLLM_VerificationToken. | ||
| keys_count_by_team: Dict[str, int] = {} | ||
| if not use_deleted_table: |
There was a problem hiding this comment.
can you put this logic into a method?
|
Also, can you check the failing mock tests? Thanks! |
3bd52c1 to
7ec8109
Compare
68852ef
into
litellm_internal_staging
Relevant issues
N/A
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
tests/test_litellm/directory, Adding at least 1 test is a hard requirement - see detailsmake test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewDelays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
CI (LiteLLM team)
Branch creation CI run
Link:
CI run for the last commit
Link:
Merge / cherry-pick CI run
Links:
Screenshots / Proof of Fix
Verification against a proxy with two teams (team A with 3 virtual keys, team B with 0):
```
/v2/team/list?team_id=<team_a> (single-team filter)
{
"team_id": "f2eabc73-ac0b-4885-8871-4b30226a2336",
"team_alias": "verify-keys-count-A-...",
"members_count": 1,
"keys_count": 3
}
/v2/team/list (full page, both teams visible)
{
"team_id": "2419f752-...",
"team_alias": "verify-keys-count-B-...",
"keys_count": 0
}
{
"team_id": "f2eabc73-...",
"team_alias": "verify-keys-count-A-...",
"keys_count": 3
}
```
Before this change, `/v2/team/list` did not expose any per-team key count, so the Teams page Resources badge (which fell back to `team.keys.length`) always rendered `0 Keys` — even on teams that owned virtual keys (the per-team detail Virtual Keys tab was unaffected since it uses `/key/list?team_id=…`).
Type
🐛 Bug Fix
Changes