diff --git a/backend/app/routes/channels.py b/backend/app/routes/channels.py index dca498e3..7919e9a8 100644 --- a/backend/app/routes/channels.py +++ b/backend/app/routes/channels.py @@ -180,7 +180,8 @@ def discover_channels( # (fresh subscriber counts/thumbnails carry through without a re-query). Only the title can # change, which affects the tie-break order → re-sort in Python instead of re-hitting the DB. need = [ch.id for ch, _, _ in rows if ch.details_synced_at is None][:DISCOVERY_ENRICH_CAP] - if need: + # Skip the quota-spending enrich for the demo account (it just sees the stub metadata). + if need and not user.is_demo: try: with quota.attribute(user.id, quota.QuotaAction.CHANNELS_DISCOVER), YouTubeClient(db, user) as yt: apply_channel_details(db, yt.get_channels(need)) @@ -402,7 +403,14 @@ def update_channel( # Opting a channel into full history should give an immediate feed: if we haven't even # fetched its recent uploads yet, do that one channel now (cheap) instead of waiting for # the scheduler. Deep paging still follows on the scheduler's next run (recent-then-deep). - if deep_turned_on and channel is not None and channel.recent_synced_at is None: + # Not for the demo account: it must not be able to trigger an immediate quota-burning backfill + # (the scheduler's deep paths are already human-only). Same guard as channel_detail's enrichment. + if ( + deep_turned_on + and channel is not None + and channel.recent_synced_at is None + and not user.is_demo + ): with quota.attribute(user.id, quota.QuotaAction.VIDEOS_BACKFILL_RECENT): run_recent_backfill(db, [channel], max_channels=1) diff --git a/backend/app/routes/feed.py b/backend/app/routes/feed.py index e5d29525..443ee19b 100644 --- a/backend/app/routes/feed.py +++ b/backend/app/routes/feed.py @@ -737,6 +737,11 @@ def get_video_detail( "duration_seconds": v.duration_seconds, } + # The DB path above is free; the off-catalog YouTube lookup below spends a quota unit, so the + # demo account can't reach it — it just sees "unknown" for a video we don't already store. + if user.is_demo: + raise HTTPException(status_code=404, detail="Unknown video") + try: with quota.attribute(user.id, quota.QuotaAction.VIDEOS_LOOKUP), YouTubeClient(db, user) as yt: items = yt.get_videos([video_id])