Delete seeded scenarios no seed file claims any more

`previous_titles` stops a rename stranding the row it left behind, but the rows
already stranded still had to be deleted by hand on every deployment. The
seeder now removes them on the next boot, which retires the stale "Road to the
Champion" demo without a database console.

Only rows with a NULL owner and `is_public` are considered, and a player's own
scenario is neither, so nothing anybody created is reachable. An adventure
started from a deleted demo survives: `adventures.scenario_id` is `ON DELETE
SET NULL`, and the adventure holds its own copies of the cards and scripts, so
it loses only the inherited cover art.

Two cases skip the sweep, because neither is an instruction to remove live
content: a seed file that fails to parse claims no title, and an empty seed
directory reads as a packaging failure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PacdRuPXSkQQy4ZYdH32hF
This commit is contained in:
parththakkar106
2026-08-28 19:19:23 +05:30
co-authored by Claude Opus 5
parent c2d3f0d8b9
commit 9398c13da5
6 changed files with 258 additions and 10 deletions
+9
View File
@@ -954,6 +954,15 @@ guest survives with no re-parenting and no migration step. Three kinds of row sh
users table: local (email NULL, not guest), guest (email NULL, guest), registered (email
set).
**A seed file owns its scenario's whole life.** `seed.py` inserts a demo that is
missing, reconciles one whose file changed, and deletes a seeded row no file claims any
more. Matching is by title, so a rename needs the old name under `previous_titles` or it
inserts a second scenario and strands the first. Only rows with a NULL owner and
`is_public` are seeded rows, which is what keeps the sweep away from anything a player
made. An adventure started from a demo that is later removed survives:
`adventures.scenario_id` is `ON DELETE SET NULL`, and the adventure holds its own copies
of the cards and scripts, so it loses only the inherited cover art.
**Guests start with a story already in progress.** `starter.py` copies a shipped export
bundle into each new guest account at the same point the row is created. An empty account
gives a visitor nothing to read, and the daily demo turns are limited, so learning what