-- 009_live_persistence.sql — persistence for live races and lobby drivers. -- -- The active race surface (lobby | countdown | racing) is now mirrored -- in Postgres. finished_races continues to be the canonical archive -- (no rename yet — it stays in the same shape and the next migration -- will unify the two under a single `races` table). -- -- live_races -- One row per active race. Status is one of -- lobby | countdown | racing. The `podium` column is reserved for -- future use (we may eventually move finished_podium into this -- table as well). -- -- live_race_drivers -- Many-to-many between live_races and drivers. The order column is -- the car's slot in the race (0..max_cars-1). -- -- lobby_drivers -- Presence of a driver in the lobby: connected / idle / racing / -- offline and the current race if racing. CREATE TABLE IF NOT EXISTS live_races ( id TEXT PRIMARY KEY, name TEXT NOT NULL, track_id TEXT NOT NULL, max_cars INT NOT NULL, laps INT NOT NULL, time_limit_s INT NOT NULL, status TEXT NOT NULL DEFAULT 'lobby' CHECK (status IN ('lobby', 'countdown', 'racing', 'cancelled')), created_ms BIGINT NOT NULL, started_ms BIGINT NOT NULL DEFAULT 0, finished_ms BIGINT NOT NULL DEFAULT 0, updated_ms BIGINT NOT NULL ); CREATE INDEX IF NOT EXISTS live_races_status_idx ON live_races (status, updated_ms DESC); CREATE INDEX IF NOT EXISTS live_races_track_idx ON live_races (track_id); CREATE TABLE IF NOT EXISTS live_race_drivers ( race_id TEXT NOT NULL REFERENCES live_races(id) ON DELETE CASCADE, driver_id TEXT NOT NULL, slot INT NOT NULL DEFAULT 0, joined_ms BIGINT NOT NULL, PRIMARY KEY (race_id, driver_id) ); CREATE INDEX IF NOT EXISTS live_race_drivers_driver_idx ON live_race_drivers (driver_id); CREATE TABLE IF NOT EXISTS lobby_drivers ( driver_id TEXT PRIMARY KEY, name TEXT NOT NULL DEFAULT '', nickname TEXT NOT NULL DEFAULT '', avatar_url TEXT NOT NULL DEFAULT '', clan_id TEXT NOT NULL DEFAULT '', clan_tag TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'idle' CHECK (status IN ('idle', 'racing', 'offline')), current_race_id TEXT NOT NULL DEFAULT '', connected_ms BIGINT NOT NULL, last_seen_ms BIGINT NOT NULL ); CREATE INDEX IF NOT EXISTS lobby_drivers_status_idx ON lobby_drivers (status);