local-dev: auto-purge terminal Dev Sandbox games on every boot
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>
This commit is contained in:
@@ -418,7 +418,7 @@ CREATE INDEX race_names_pending_eligible_idx
|
||||
-- finished) and the container-state escape hatch (removed) used by
|
||||
-- reconciliation when the recorded container has disappeared.
|
||||
CREATE TABLE runtime_records (
|
||||
game_id uuid PRIMARY KEY,
|
||||
game_id uuid PRIMARY KEY REFERENCES games (game_id) ON DELETE CASCADE,
|
||||
status text NOT NULL,
|
||||
current_container_id text,
|
||||
current_image_ref text,
|
||||
@@ -465,7 +465,7 @@ CREATE TABLE engine_versions (
|
||||
-- roster reads. The partial UNIQUE on (game_id, race_name) enforces the
|
||||
-- one-race-per-game invariant at the storage boundary.
|
||||
CREATE TABLE player_mappings (
|
||||
game_id uuid NOT NULL,
|
||||
game_id uuid NOT NULL REFERENCES games (game_id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL,
|
||||
race_name text NOT NULL,
|
||||
engine_player_uuid uuid NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user