From bf240cef9e32c6c46dbe1d6be614646a81ef7d18 Mon Sep 17 00:00:00 2001 From: Dorian Date: Thu, 30 Jul 2026 22:11:29 -0400 Subject: [PATCH] =?UTF-8?q?fix(09-02):=20sync=20migrate.ts=20DDL=20with=20?= =?UTF-8?q?schema.ts=20=E2=80=94=20fixes=2015=20pre-existing=20auth/tourna?= =?UTF-8?q?ment=20test=20failures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deviation (Rule 1 — auto-fix bug), out-of-scope-but-cheap per plan 09-02's explicit allowance. server/src/db/migrate.ts (the standalone `pnpm migrate` CLI script) had drifted from server/src/db/schema.ts: it was missing 7 tables (payments, wallet_connections, bets, tournaments, tournament_entries, analytics, tournament_matches) and several bots/fights columns (sats_won, sats_wagered, has_wallet, zaps_received, bot_type, mode, pot_sats, payout_status, current_season). server/src/db/startup.ts's runMigrations() (the one actually called from index.ts at server boot) already had the correct, up-to-date DDL — migrate.ts was the stale duplicate. Brought it back in sync, column-for-column and table-for-table, against schema.ts. Route-level tests (auth.test.ts, auth-audit.test.ts, auth-edge.test.ts, tournaments.test.ts) hit the real db/index.ts singleton against the on-disk, gitignored server/data/botfights.db, which only startup.ts or this migrate.ts script populate — vitest itself never runs a migration. Running `pnpm --filter server migrate` against a fresh DB with the fixed script now creates all tables/columns; full server suite went from 15 failed / 789 passed to 6 failed / 798 passed, with the remaining 6 all pre-existing timing/perf flakes unrelated to auth (answers.test.ts, lifecycle.test.ts x2, bot-auth.test.ts, docs.test.ts x2 — CPU-contention sensitive, matches deferred-items.md's documented flake class). Co-Authored-By: Claude Fable 5 --- server/src/db/migrate.ts | 102 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/server/src/db/migrate.ts b/server/src/db/migrate.ts index 04caa99..a121f1c 100644 --- a/server/src/db/migrate.ts +++ b/server/src/db/migrate.ts @@ -31,6 +31,12 @@ sqlite.exec(` last_fight_at TEXT, consecutive_errors INTEGER NOT NULL DEFAULT 0, last_error_at TEXT, + customization TEXT, + sats_won INTEGER NOT NULL DEFAULT 0, + sats_wagered INTEGER NOT NULL DEFAULT 0, + has_wallet INTEGER NOT NULL DEFAULT 0, + zaps_received INTEGER NOT NULL DEFAULT 0, + bot_type TEXT NOT NULL DEFAULT 'regular', created_at TEXT NOT NULL ); @@ -47,6 +53,10 @@ sqlite.exec(` scheduled_at TEXT, started_at TEXT, ended_at TEXT, + mode TEXT NOT NULL DEFAULT 'free', + pot_sats INTEGER NOT NULL DEFAULT 0, + payout_status TEXT, + current_season TEXT, created_at TEXT NOT NULL ); @@ -66,6 +76,89 @@ sqlite.exec(` narration TEXT, created_at TEXT NOT NULL ); + + CREATE TABLE IF NOT EXISTS payments ( + id TEXT PRIMARY KEY, + fight_id TEXT REFERENCES fights(id), + bot_id TEXT NOT NULL REFERENCES bots(id), + direction TEXT NOT NULL, + amount_sats INTEGER NOT NULL, + method TEXT NOT NULL, + status TEXT NOT NULL DEFAULT 'pending', + invoice TEXT, + preimage TEXT, + cashu_token TEXT, + error_reason TEXT, + created_at TEXT NOT NULL, + confirmed_at TEXT, + refunded_at TEXT + ); + + CREATE TABLE IF NOT EXISTS wallet_connections ( + id TEXT PRIMARY KEY, + bot_id TEXT NOT NULL UNIQUE REFERENCES bots(id), + method TEXT NOT NULL, + connection_data TEXT NOT NULL, + created_at TEXT NOT NULL, + last_used_at TEXT + ); + + CREATE TABLE IF NOT EXISTS bets ( + id TEXT PRIMARY KEY, + fight_id TEXT NOT NULL REFERENCES fights(id), + bettor_pubkey TEXT NOT NULL, + bot_id TEXT NOT NULL REFERENCES bots(id), + amount_sats INTEGER NOT NULL, + odds_at_placement REAL NOT NULL, + cashu_token TEXT NOT NULL, + status TEXT NOT NULL DEFAULT 'pending', + payout_sats INTEGER, + payout_token TEXT, + created_at TEXT NOT NULL, + settled_at TEXT + ); + + CREATE TABLE IF NOT EXISTS tournaments ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + format TEXT NOT NULL, + size INTEGER NOT NULL, + entry_sats INTEGER NOT NULL DEFAULT 0, + prize_sats INTEGER NOT NULL DEFAULT 0, + status TEXT NOT NULL DEFAULT 'open', + current_round INTEGER NOT NULL DEFAULT 0, + season_id TEXT, + created_at TEXT NOT NULL, + started_at TEXT, + finished_at TEXT + ); + + CREATE TABLE IF NOT EXISTS tournament_entries ( + id TEXT PRIMARY KEY, + tournament_id TEXT NOT NULL REFERENCES tournaments(id), + bot_id TEXT NOT NULL REFERENCES bots(id), + seed INTEGER NOT NULL DEFAULT 0, + eliminated INTEGER NOT NULL DEFAULT 0, + created_at TEXT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS analytics ( + date TEXT NOT NULL, + metric TEXT NOT NULL, + value INTEGER NOT NULL DEFAULT 0 + ); + + CREATE TABLE IF NOT EXISTS tournament_matches ( + id TEXT PRIMARY KEY, + tournament_id TEXT NOT NULL REFERENCES tournaments(id), + round INTEGER NOT NULL, + match_index INTEGER NOT NULL, + bot_a_id TEXT REFERENCES bots(id), + bot_b_id TEXT REFERENCES bots(id), + fight_id TEXT REFERENCES fights(id), + winner_id TEXT REFERENCES bots(id), + status TEXT NOT NULL DEFAULT 'pending' + ); `) // Migrations for existing databases @@ -76,6 +169,15 @@ const migrations = [ `ALTER TABLE bots ADD COLUMN consecutive_errors INTEGER NOT NULL DEFAULT 0`, `ALTER TABLE bots ADD COLUMN last_error_at TEXT`, `ALTER TABLE bots ADD COLUMN customization TEXT`, + `ALTER TABLE bots ADD COLUMN sats_won INTEGER NOT NULL DEFAULT 0`, + `ALTER TABLE bots ADD COLUMN sats_wagered INTEGER NOT NULL DEFAULT 0`, + `ALTER TABLE bots ADD COLUMN has_wallet INTEGER NOT NULL DEFAULT 0`, + `ALTER TABLE bots ADD COLUMN zaps_received INTEGER NOT NULL DEFAULT 0`, + `ALTER TABLE bots ADD COLUMN bot_type TEXT NOT NULL DEFAULT 'regular'`, + `ALTER TABLE fights ADD COLUMN mode TEXT NOT NULL DEFAULT 'free'`, + `ALTER TABLE fights ADD COLUMN pot_sats INTEGER NOT NULL DEFAULT 0`, + `ALTER TABLE fights ADD COLUMN payout_status TEXT`, + `ALTER TABLE fights ADD COLUMN current_season TEXT`, ] for (const sql of migrations) {