-- Platform columns and tables added in the 2026 rewrite. Idempotent: safe on -- databases where the old migrate-platform script already ran. ALTER TABLE "user" ADD COLUMN IF NOT EXISTS osu_id integer; ALTER TABLE "user" ADD COLUMN IF NOT EXISTS country_code text; ALTER TABLE "user" ADD COLUMN IF NOT EXISTS discord_id text; ALTER TABLE "user" ADD COLUMN IF NOT EXISTS banned_at timestamptz; ALTER TABLE "user" ADD COLUMN IF NOT EXISTS timezone text; ALTER TABLE "user" ADD COLUMN IF NOT EXISTS available_hours jsonb; CREATE UNIQUE INDEX IF NOT EXISTS user_osu_id_idx ON "user" (osu_id) WHERE osu_id IS NOT NULL; ALTER TABLE player_rating ADD COLUMN IF NOT EXISTS provisional boolean NOT NULL DEFAULT true; UPDATE player_rating SET provisional = false WHERE wins + losses >= 5 AND provisional; CREATE TABLE IF NOT EXISTS team_rating ( team_id uuid PRIMARY KEY REFERENCES team(id) ON DELETE CASCADE, elo integer NOT NULL DEFAULT 1000, wins integer NOT NULL DEFAULT 0, losses integer NOT NULL DEFAULT 0, updated_at timestamptz NOT NULL DEFAULT now() ); ALTER TABLE mappool ADD COLUMN IF NOT EXISTS origin text; ALTER TABLE mappool ADD COLUMN IF NOT EXISTS rating real; ALTER TABLE match ADD COLUMN IF NOT EXISTS game text NOT NULL DEFAULT 'osu'; ALTER TABLE match ADD COLUMN IF NOT EXISTS kind text NOT NULL DEFAULT 'custom'; ALTER TABLE match ADD COLUMN IF NOT EXISTS procedure jsonb; ALTER TABLE match ADD COLUMN IF NOT EXISTS deadline_at timestamptz; ALTER TABLE match ADD COLUMN IF NOT EXISTS elo_applied boolean NOT NULL DEFAULT false; ALTER TABLE match_queue ADD COLUMN IF NOT EXISTS format integer NOT NULL DEFAULT 1; CREATE TABLE IF NOT EXISTS match_event ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), match_id uuid NOT NULL REFERENCES match(id) ON DELETE CASCADE, type text NOT NULL, detail text, created_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_match_event_match ON match_event (match_id, created_at); CREATE TABLE IF NOT EXISTS system_state ( id text PRIMARY KEY, draining boolean NOT NULL DEFAULT false, reason text, updated_at timestamptz NOT NULL DEFAULT now() );