import fs from 'fs' import path from 'path' import { db } from './db' export async function runMigrations() { const migrationsDir = path.join(process.cwd(), 'migrations') // Create migrations tracking table await db.query(` CREATE TABLE IF NOT EXISTS _migrations ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE, applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ) `) const files = fs.readdirSync(migrationsDir) .filter(f => f.endsWith('.sql') && !f.startsWith('._')) .sort() for (const file of files) { const { rows } = await db.query( 'SELECT id FROM _migrations WHERE name = $1', [file], ) if (rows.length > 0) continue // already applied const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf8') console.log(`[migrate] Applying ${file}...`) const client = await db.connect() try { await client.query('BEGIN') await client.query(sql) await client.query('INSERT INTO _migrations (name) VALUES ($1)', [file]) await client.query('COMMIT') console.log(`[migrate] ✅ ${file} applied`) } catch (err) { await client.query('ROLLBACK') console.error(`[migrate] ❌ ${file} failed:`, err) throw err } finally { client.release() } } console.log('[migrate] All migrations up to date') }