Skip to content

feat(ai-accounts): sort accounts by remaining quota - #929

Merged
kittors merged 2 commits into
devfrom
feat/ai-accounts-quota-sort
Aug 19, 2026
Merged

feat(ai-accounts): sort accounts by remaining quota#929
kittors merged 2 commits into
devfrom
feat/ai-accounts-quota-sort

Conversation

@kittors

@kittors kittors commented Aug 19, 2026

Copy link
Copy Markdown
Owner

What

The AI accounts list (/access/ai-accounts) could only be ordered by name. With many accounts, finding one that still has headroom meant reading every card.

Adds a sort control to the toolbar: by name (default), least quota left first, most quota left first.

This is the page I should have built #928 on. That PR added the same control to AI providers β€” I matched the nav label instead of the page you meant. This one is on AI accounts.

Design decisions worth reviewing

Ranked by the tightest quota the card actually shows. Scoping to the visible slots matters: antigravity reports both a 5h and a weekly bucket but the card renders only the 5h one. Ranking by a number the operator cannot see on the card reads as a broken sort. The rank therefore runs through resolveQuotaCardSlots β€” the same function that decides what the card displays.

Sorting pulls the full status snapshot once. This is the part that made a backend change look necessary, and then turned out not to need one:

The list loads status only for the accounts on the current page (visibleStatusScopeKey). That is right for rendering and useless for ordering β€” sorting a page by numbers only that page has just shuffles it. But GET /ai-accounts/status already returns every account when no auth_index filter is supplied, so the data was one parameterless call away. The order is applied in filteredFiles, before the slice into pages.

Nothing is fetched while sorting by name, so the default view is unaffected.

Unknown sorts last in both directions, keeping name order among themselves. Unknown is not empty and not full; floating it to the top of either direction would bury exactly what the operator opened the view to find. A failed snapshot leaves everything unranked, preserving name order rather than presenting a partial order as authoritative.

Preference and fetch state are module-scoped. AuthFilesPage.tsx (1210) and AuthFilesFilesTab.tsx (2579) are both frozen at their size baselines, and the gate only permits shrinking β€” threading this through as props was not available. The list and the toolbar control read the shared value independently. Neither file is touched by this change. The control lives in AuthFilesToolbarActions.tsx, which was itself extracted to keep the tab under the ratchet.

The control shows a spinner while the snapshot loads; without it the button looks inert for the duration of the request, which reads as broken.

No backend change

GET /ai-accounts/status with no filter already returns every account with its quota windows (ListStatus treats an empty filter as "all"). Verified in internal/management/aiaccountstatus/service.go.

Testing

7 new tests covering the rank calculation β€” including that antigravity's hidden weekly window is not used β€” and the shared preference (default, cross-instance sharing, persistence, unrecognised stored value).

tsc, oxlint, and all four structure gates pass. Full pages/auth-files suite green at 236 tests.

Not verified in a browser

I started the dev server and stopped at the login screen β€” I don't enter credentials. The control's appearance and the drop-down interaction are covered by tests but not by eye.

πŸ€– Generated with Claude Code

kittors and others added 2 commits August 19, 2026 23:28
The AI accounts list could only be ordered by name. With many accounts,
finding one that still has headroom meant reading every card.

Adds a sort control to the toolbar: by name (default), least quota left
first, most quota left first.

An account's position is decided by the tightest quota its card actually
shows. Scoping it to the visible slots matters: antigravity reports both
a 5h and a weekly bucket but the card renders only the 5h one, and
ranking by a number the operator cannot see reads as a broken sort.

Sorting pulls the full status snapshot once. The list loads status only
for the accounts on the current page β€” correct for rendering, useless for
ordering, since sorting a page by numbers only that page has just
shuffles it. The endpoint already returns every account when no
auth_index filter is given, so no backend change was needed. The order is
applied before the slice into pages.

Accounts with no reading sort last in both directions and keep name order
among themselves. Unknown is not empty and not full; floating it to the
top of either direction would bury what the operator opened the view to
find. A failed snapshot leaves everything unranked, which preserves name
order rather than presenting a partial order as authoritative.

The preference and the fetch state are module-scoped and the preference
is persisted. AuthFilesPage.tsx and AuthFilesFilesTab.tsx are both frozen
at their size baselines, so threading this through as props was not
available; the list and the toolbar control read the shared value
independently. Neither file is touched by this change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Matches the column-count control it sits beside β€” same affordance for the
same kind of choice, and no second popover implementation on a toolbar
that already has one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kittors
kittors force-pushed the feat/ai-accounts-quota-sort branch from 30b51f6 to 430535d Compare August 19, 2026 15:28
@kittors
kittors merged commit 9a14ae7 into dev Aug 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant