Skip to content

feat(usage): attribute Sources rows to user accounts in admin view#9935

Merged
mudler merged 1 commit into
masterfrom
worktree-usage-sources-admin-user-attribution
May 21, 2026
Merged

feat(usage): attribute Sources rows to user accounts in admin view#9935
mudler merged 1 commit into
masterfrom
worktree-usage-sources-admin-user-attribution

Conversation

@localai-bot
Copy link
Copy Markdown
Collaborator

Follow-up to #9920.

Problem

Admin Sources tab in #9920 shows per-API-key and per-source totals, but:

  • Each named-key row only shows the key label - admins can't tell which user owns the key.
  • All users' Web UI session traffic is lumped into a single global "Web UI" row.

Even though every UsageRecord carries user_id/user_name, the
by_key roll-up dropped those fields, and by_source only grouped
by source class.

Change

Backend (core/http/auth/usage.go):

  • KeyTotal gains UserID + UserName. by_key now groups by
    (api_key_id, api_key_name, user_id, user_name).
  • New SourceTotals.ByUserSource []UserSourceTotal roll-up groups
    (source, user_id, user_name) for sources without a key identity
    (web, legacy). Populated only on the admin path
    (includeLegacy=true); the non-admin endpoint stays unchanged for
    backwards compatibility.

Frontend (SourcesTable.jsx):

  • New showUserColumn prop (admin-only). Renders a User column,
    extends search to match user name/id, and expands the Web UI /
    Legacy pseudo-rows from one global row to one row per user using
    by_user_source.

i18n: adds usage.sources.sortUser = "User".

Test plan

  • ginkgo -tags auth ./core/http/auth/ - 150/150 pass (3 new specs)
  • go test -tags auth ./core/http/middleware/... - clean
  • ginkgo -tags auth ./core/http/routes/ - 63/63 pass
  • go vet -tags auth ./core/http/... - clean
  • npm run build in core/http/react-ui/ - clean
  • Manual smoke: admin Sources tab shows User column on every row
  • Manual smoke: admin Web UI traffic shows per-user rows
  • Manual smoke: non-admin Sources tab unchanged (no User column)
  • Manual smoke: search input matches user names/emails

The merged feature (#9920) let admins see per-API-key and per-source
totals but did not surface which user owned each key, and lumped
every user's Web UI traffic into a single global Web UI row. This
makes the admin Sources tab properly per-user attributable:

- KeyTotal gains UserID + UserName, populated from the snapshot the
  usage middleware already records. The by_key roll-up now groups by
  (api_key_id, api_key_name, user_id, user_name).
- New SourceTotals.ByUserSource roll-up groups (source, user_id,
  user_name) for sources without a key identity (web, legacy). Only
  populated on the admin path (includeLegacy=true); the non-admin
  endpoint stays unchanged for backwards compatibility.
- SourcesTable accepts showUserColumn={isAdmin}; admin view renders
  a User column, makes the search match user name/id, and expands
  Web UI / legacy pseudo-rows from the global aggregate to one row
  per user using by_user_source.

Refs: #9862
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
@mudler mudler merged commit f0cb02a into master May 21, 2026
57 checks passed
@mudler mudler deleted the worktree-usage-sources-admin-user-attribution branch May 21, 2026 21:23
@localai-bot localai-bot added the enhancement New feature or request label May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants