diff --git a/server/src/db/connection.ts b/server/src/db/connection.ts index 40b2e16..b820a79 100644 --- a/server/src/db/connection.ts +++ b/server/src/db/connection.ts @@ -112,6 +112,44 @@ const runMigrations = () => { db.exec('PRAGMA foreign_keys = ON'); userTableInfo2 = db.prepare("PRAGMA table_info(users)").all() as { name: string }[]; } + + // Fix any tables with stale FK references to users_old (SQLite quirk after table rename) + const tablesWithBrokenFK = db.prepare(` + SELECT name, sql FROM sqlite_master + WHERE type='table' AND sql LIKE '%users_old%' + `).all() as { name: string; sql: string }[]; + + if (tablesWithBrokenFK.length > 0) { + console.log('Fixing stale FK references to users_old...'); + db.exec('PRAGMA foreign_keys = OFF'); + db.exec('BEGIN'); + + for (const table of tablesWithBrokenFK) { + const fixedSql = table.sql.replace(/["']?users_old["']?/g, 'users'); + const tempName = `${table.name}_fk_fix`; + + // Get column names + const columns = db.prepare(`PRAGMA table_info(${table.name})`).all() as { name: string }[]; + const columnList = columns.map(c => c.name).join(', '); + + // Recreate table with fixed FK + db.exec(fixedSql.replace(`CREATE TABLE ${table.name}`, `CREATE TABLE ${tempName}`)); + db.exec(`INSERT INTO ${tempName} SELECT ${columnList} FROM ${table.name}`); + db.exec(`DROP TABLE ${table.name}`); + db.exec(`ALTER TABLE ${tempName} RENAME TO ${table.name}`); + + console.log(` Fixed FK in table: ${table.name}`); + } + + // Recreate indexes for affected tables + db.exec('CREATE INDEX IF NOT EXISTS idx_quizzes_user ON quizzes(user_id)'); + db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_quizzes_share_token ON quizzes(share_token)'); + db.exec('CREATE INDEX IF NOT EXISTS idx_payments_user ON payments(user_id)'); + + db.exec('COMMIT'); + db.exec('PRAGMA foreign_keys = ON'); + } + if (didDropApiKeyColumns) { logOnce( 'migration.users_drop_api_keys',