- uvicorn --log-config (log_config.json): timestamped formatters for uvicorn
access/error and the app's own "subfeed" loggers (ms precision)
- Log key activity: startup/shutdown, login/denied, token refresh, YouTube API
errors, subscription imports, sync pause/resume
- Background sync jobs no longer swallow errors silently — failures in RSS poll,
backfill, enrichment, autotag and resync are logged with tracebacks
- Vite + React + TS + Tailwind SPA served by FastAPI (multi-stage Docker build)
- Four color schemes (Midnight default, Forest, Slate, YouTube) x dark/light,
adjustable text size; persisted to user preferences and localStorage
- Header search, grid/list toggle, theme menu; sidebar filters (show state,
sort, include Shorts/live, language + topic tag chips with any/all matching)
- Infinite-scroll feed of video cards; click opens youtube.com in a new tab;
per-video watched / saved / hidden actions with optimistic updates
- SPA fallback routing; login screen for unauthenticated users
- Tag and ChannelTag models + migration 0003 (partial unique indexes split
system vs per-user tag names)
- Offline language detection (py3langid) constrained to a curated language set,
with the channel's declared default language as a strong prior
- Topic tags mapped from YouTube topicDetails + dominant video category; the
generic "Lifestyle" catch-all is intentionally dropped
- System (auto) tags are regenerated idempotently and never touch user tags;
orphaned system tags are cleaned up
- GET /api/tags and admin POST /api/tags/recompute; scheduled autotag job
- Free per-channel RSS reader for quota-less fresh-video detection
- Recent-first backfill (configurable: 100 videos / 1 year) plus resumable deep
backfill from the uploads playlist
- Enrichment via videos.list: duration, view/like counts, category, topics,
language, Shorts heuristic and livestream/premiere classification
- Reusable sync runners + APScheduler jobs (rss / enrich / backfill), all
quota-aware with a reserve so backfill never starves fresh enrichment
- Manual triggers: POST /api/sync/{rss,backfill,enrich}
- Exact insert counting via RETURNING with in-batch de-duplication
- Channel/Subscription/Video/ApiQuotaUsage models + migration 0002
- Synchronous YouTube Data API client with OAuth token refresh and per-call
quota accounting (API key preferred for public reads when configured)
- Subscription import: upsert channels + subscription links, prune unsubscribed,
fetch channel details (uploads playlist, topics, stats, handle, country)
- Central quota guard tracking units per US-Pacific day against a daily budget
- POST /api/sync/subscriptions and GET /api/sync/status endpoints
- docker-compose with Postgres 16 + slim Python API image
- FastAPI app with session middleware, health endpoint, static login page
- Google OAuth (Authlib) with email invite-list whitelist; admin role support
- User + OAuthToken models; refresh tokens encrypted at rest (Fernet)
- Alembic migrations, run automatically on container startup
- Postgres backup/restore scripts for portability between machines