a1ba5ee093
Replace Supabase auth and search runtime with a local Fastify API, PostgreSQL/PostGIS schema, and local session handling. Scaffold the worker and deep-research foundations while keeping the existing research, dashboard, and map flows running on the new backend.
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import 'dotenv/config';
|
|
import { readdir, readFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { getDbPool } from '../../server/src/db/pool.js';
|
|
|
|
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
const migrationsDir = path.resolve(currentDir, '../migrations');
|
|
|
|
async function run() {
|
|
const pool = getDbPool();
|
|
const client = await pool.connect();
|
|
|
|
try {
|
|
await client.query(`
|
|
create table if not exists public.schema_migrations (
|
|
id text primary key,
|
|
applied_at timestamptz not null default now()
|
|
)
|
|
`);
|
|
|
|
const appliedRows = await client.query<{ id: string }>('select id from public.schema_migrations');
|
|
const appliedIds = new Set(appliedRows.rows.map((row) => row.id));
|
|
|
|
const migrationFiles = (await readdir(migrationsDir))
|
|
.filter((entry) => entry.endsWith('.sql'))
|
|
.sort((left, right) => left.localeCompare(right));
|
|
|
|
for (const migrationFile of migrationFiles) {
|
|
if (appliedIds.has(migrationFile)) {
|
|
continue;
|
|
}
|
|
|
|
const migrationPath = path.join(migrationsDir, migrationFile);
|
|
const sql = await readFile(migrationPath, 'utf8');
|
|
|
|
console.log(`Applying migration ${migrationFile}`);
|
|
await client.query('begin');
|
|
await client.query(sql);
|
|
await client.query('insert into public.schema_migrations (id) values ($1)', [migrationFile]);
|
|
await client.query('commit');
|
|
}
|
|
|
|
console.log('Migrations complete');
|
|
} catch (error) {
|
|
await client.query('rollback');
|
|
throw error;
|
|
} finally {
|
|
client.release();
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
await run();
|