CREATE TABLE users ( id TEXT PRIMARY KEY, kind TEXT NOT NULL CHECK (kind IN ('guest','member')), nickname TEXT NOT NULL, avatar_url TEXT, use_avatar INTEGER NOT NULL DEFAULT 1, settings_json TEXT NOT NULL DEFAULT '{}', nick_changed_at INTEGER, nick_change_count INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL, last_seen_at INTEGER NOT NULL, deleted_at INTEGER ); CREATE TABLE oauth_accounts ( provider TEXT NOT NULL, provider_user_id TEXT NOT NULL, user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, username TEXT, created_at INTEGER NOT NULL, PRIMARY KEY (provider, provider_user_id) ); CREATE INDEX oauth_accounts_user ON oauth_accounts(user_id); CREATE TABLE sessions ( token_hash TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL, last_used_at INTEGER NOT NULL, user_agent TEXT ); CREATE INDEX sessions_user ON sessions(user_id); CREATE TABLE rooms ( id TEXT PRIMARY KEY, code TEXT NOT NULL, host_id TEXT NOT NULL, game_id TEXT NOT NULL, status TEXT NOT NULL CHECK (status IN ('lobby','playing','finished','paused','broken','closed')), visibility TEXT NOT NULL, config_json TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, closed_at INTEGER ); CREATE UNIQUE INDEX rooms_open_code ON rooms(code) WHERE status <> 'closed'; CREATE INDEX rooms_status ON rooms(status); CREATE TABLE room_state ( room_id TEXT PRIMARY KEY REFERENCES rooms(id) ON DELETE CASCADE, seq INTEGER NOT NULL, state_json TEXT NOT NULL, updated_at INTEGER NOT NULL ); CREATE TABLE room_log ( room_id TEXT NOT NULL, seq INTEGER NOT NULL, game_no INTEGER NOT NULL, actor_id TEXT, kind TEXT NOT NULL, data_json TEXT NOT NULL, at INTEGER NOT NULL, PRIMARY KEY (room_id, seq) ); CREATE TABLE games ( id TEXT PRIMARY KEY, room_id TEXT NOT NULL, game_no INTEGER NOT NULL, game_id TEXT NOT NULL, options_json TEXT NOT NULL, seed_hash TEXT NOT NULL, seed TEXT, started_at INTEGER NOT NULL, ended_at INTEGER, end_reason TEXT, result_json TEXT ); CREATE INDEX games_room ON games(room_id); CREATE TABLE game_players ( game_pk TEXT NOT NULL REFERENCES games(id) ON DELETE CASCADE, user_id TEXT NOT NULL, seat INTEGER NOT NULL, rank INTEGER, score REAL, PRIMARY KEY (game_pk, user_id) ); CREATE INDEX game_players_user ON game_players(user_id); CREATE TABLE user_stats ( user_id TEXT NOT NULL, game_id TEXT NOT NULL, played INTEGER NOT NULL DEFAULT 0, wins INTEGER NOT NULL DEFAULT 0, draws INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (user_id, game_id) );