siftlode/backend/app/routes
npeter83 f255728f75 feat(stats): per-user API quota attribution + admin usage page
Track who burned how much YouTube API quota. A QuotaEvent audit log (migration
0009) records every spend with the triggering user (NULL = background/system) and
an action label, set via a request/job-scoped contextvar (quota.attribute) so no
call signatures change. User-initiated work (sync subscriptions, unsubscribe,
opt-in recent backfill, manual enrich) attributes to the user; scheduler work to
System, split by action.

- backend: QuotaEvent model + migration 0009; quota.attribute() contextvar;
  record_usage logs events; entry points wrapped (routes/sync, routes/channels,
  scheduler); GET /api/quota/my-usage + GET /api/quota/admin
- frontend: admin-only Stats page (header nav, page=stats) with daily bars +
  per-user breakdown by action and range picker; 'Your API usage' in Settings ->
  Sync for every user

Verified: attribution + endpoints compute correctly; events are per-user vs System.
2026-06-12 02:47:55 +02:00
..
__init__.py feat: M1 foundation — compose stack, FastAPI, Google OAuth, encrypted tokens 2026-06-11 01:01:37 +02:00
admin.py feat(m5c): onboarding — DB invites, request-access, admin approval, email 2026-06-12 01:43:07 +02:00
channels.py feat(stats): per-user API quota attribution + admin usage page 2026-06-12 02:47:55 +02:00
feed.py fix(ui): portal tooltips, opaque glass, settings rail+stable height, notif test, channel help 2026-06-11 21:30:25 +02:00
health.py feat: M1 foundation — compose stack, FastAPI, Google OAuth, encrypted tokens 2026-06-11 01:01:37 +02:00
me.py feat(m5c): onboarding — DB invites, request-access, admin approval, email 2026-06-12 01:43:07 +02:00
quota.py feat(stats): per-user API quota attribution + admin usage page 2026-06-12 02:47:55 +02:00
sync.py feat(stats): per-user API quota attribution + admin usage page 2026-06-12 02:47:55 +02:00
tags.py feat(m5a): channel manager, tabbed settings panel, per-user sync status 2026-06-11 20:45:48 +02:00