feat!: remove the shared demo account

The demo account — one shared user that whitelisted emails entered from
the login page, reset on a schedule — goes end to end (owner decision,
E34): demo.py and the reset job, users.is_demo and demo_whitelist
(migration 0098 deletes the demo user, its audit rows, the reset job's
override and notices, then drops the column and table; the downgrade
restores the empty schema), the /auth/demo entry, the admin whitelist and
reset, the Demo tab, the banner, the login page's "Try the demo", and
every is_demo branch in routes, userscope, scheduler and the UI.

require_human only ever refused the demo account, so its 87 uses become
current_user (owner-approved); require_write_scope keeps its own check.
The login page's "or" divider now shows only beside the Google button:
without the demo entry under it, an instance without Google would have
said "or" to nothing.

A contract test (removedFeatures) fails on the word anywhere in the
backend, frontend, e2e or scripts — seen red on a planted hit. Size
ceilings tightened for the modules that shrank; admin.py is back under
the limit.
This commit is contained in:
2026-10-05 00:19:38 +02:00
parent cca3315836
commit 6d8b7be6d8
109 changed files with 487 additions and 1400 deletions
@@ -69,7 +69,6 @@
"shorts": "Probes youtube.com/shorts to mark which videos are Shorts. If it stops, Shorts aren't separated from normal videos in the Feed.",
"subscriptions": "Re-imports every user's YouTube subscriptions. If it stops, channels subscribed to or dropped on YouTube aren't reflected here.",
"playlist_sync": "Mirrors each user's YouTube playlists into the app. If it stops, changes to your YouTube playlists don't show up locally.",
"demo_reset": "Resets the shared demo account (its playlists and state) so every visitor starts from the same sandbox. Does nothing when there is no demo account. If it stops, the demo keeps whatever the last visitor left behind.",
"maintenance": "Finds videos that can no longer be played (deleted, made private, abandoned premieres), hides them from the Feed and removes them after a grace period; re-checks the least-recently-checked videos. If it stops, dead videos linger in the catalogue.",
"explore_cleanup": "Removes channels you explored but never subscribed to (and their videos) after a grace period, so curiosity browsing doesn't pile up in the catalogue. If it stops, abandoned explored channels linger.",
"download_gc": "Deletes downloaded files past their retention window, reclaims space no one is holding anymore, and warns owners before a shared file expires. If it stops, old downloads pile up and disk space isn't freed.",
@@ -90,7 +89,6 @@
"subscriptions": "Subscription sync from YouTube",
"playlist_sync": "Playlist sync from YouTube",
"maintenance": "Maintenance + validation",
"demo_reset": "Demo account reset",
"explore_cleanup": "Explored-channel cleanup",
"download_gc": "Download cleanup",
"plex_sync": "Plex library sync",
@@ -139,7 +137,6 @@
"revalidated": "revalidated",
"flagged": "flagged",
"skipped": "skipped",
"playlists_seeded": "playlists seeded",
"expired": "expired",
"videos_deleted": "videos deleted",
"channels_deleted": "channels deleted",
@@ -183,7 +180,6 @@
"disabled": "disabled",
"PlexserverURLortokenisnotconfigured": "Plex server URL or token is not configured",
"tmdbapikeynotset": "TMDB API key not set",
"nodemoaccount": "no demo account",
"noserviceuser": "no service user",
"syncpaused": "sync paused",
"lowquota": "low quota",