Previously a cancelled / finished / start_failed sandbox game would hang in the dev user's lobby until manually cleaned up — `make up` would create a new running game alongside it but the dead tiles piled up. Now backend's `devsandbox.Bootstrap` deletes every terminal sandbox game owned by the dev user before find-or-create runs, so the lobby always shows exactly one running tile. Schema: `runtime_records` and `player_mappings` gain `ON DELETE CASCADE` on their `game_id` foreign keys so a single `DELETE FROM games` cleans every referencing row in one write. Pre-prod migration rule applies — change goes into `00001_init.sql`, not a new migration. API: `lobby.Service.DeleteGame` is the new destructive helper that backs the bootstrap purge. It bypasses the cancel-cascade-notify pipeline; production callers must stay on the regular lifecycle. The dev-sandbox docs in `tools/local-dev/README.md` spell out the new behaviour. Tests: - backend/internal/lobby/lobby_e2e_test.go gains `TestDeleteGameCascadesEverything` proving CASCADE works end-to-end against a real Postgres testcontainer. - backend/internal/devsandbox keeps its existing terminal-status contract test; the new `purgeTerminalSandboxGames` helper rides on the same `terminalSandboxStatus` predicate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Backend migrations
Goose migrations embedded into the backend binary by embed.go. Applied
at startup before any listener opens (see internal/postgres).
Pre-production single-file rule
While the platform is not yet in production, every schema change goes
into the existing 00001_init.sql file rather than a new
00002_*-prefixed file. The intent is to keep the schema in one
canonical place so reviewers and developers do not have to reconstruct
the latest shape from a chain of incremental migrations.
Operationally this means that pulling a branch with schema changes requires a fresh database — the only consumer today is local development and integration tests, both of which spin up disposable Postgres instances.
Remove this rule before the first production deployment. From that point on every schema change must be a new migration file with a monotonically increasing prefix, and
00001_init.sqlbecomes immutable history.
If you need to make a change, edit 00001_init.sql directly. Down
migrations should still be kept in sync (they live at the bottom of the
file — currently a single DROP SCHEMA backend CASCADE).