refactor: auto-run DB migration at startup, robust schema.sql path resolution

This commit is contained in:
asepharyana
2026-07-06 22:32:06 +07:00
parent 0ad783b794
commit 2d3d7891a0
2 changed files with 62 additions and 10 deletions
+37 -1
View File
@@ -3,7 +3,37 @@ import { config } from '../env';
import { getErrorMessage } from '../utils/file';
import logger from '../utils/logger';
const schemaSql = await Bun.file('schema.sql').text();
/**
* Run raw SQL migration from schema.sql.
* Safe to call multiple times — all statements use IF NOT EXISTS.
*/
export const runMigration = async (): Promise<void> => {
// In compiled dist: import.meta.dir = .../dist/
// In source via bun --hot: import.meta.dir = .../src/db/
const dir = import.meta.dir || '';
const candidates = [
dir + '/../../schema.sql', // from dist/
dir + '/../schema.sql', // from src/ (bun --hot src/index.ts)
dir + '/../schema.sql', // from src/db/ (bun --hot src/db/migrate.ts)
dir + '/schema.sql', // from src/ (bun run db:migrate)
];
let schemaSql: string | null = null;
for (const p of candidates) {
const file = Bun.file(p);
const exists = await file.exists();
if (exists) {
schemaSql = await file.text();
break;
}
}
if (!schemaSql) {
logger.error('Migration failed: schema.sql not found (tried ' + candidates.join(', ') + ')');
process.exitCode = 1;
return;
}
const sql = postgres(config.databaseUrl, { max: 1 });
try {
@@ -15,3 +45,9 @@ try {
} finally {
await sql.end();
}
};
// When run directly: `bun src/db/migrate.ts` or `bun dist/migrate.js`
if (import.meta.path === Bun.main) {
await runMigration();
}
+16
View File
@@ -14,6 +14,22 @@ import logger from './utils/logger';
import { metricsCollector } from './utils/metrics';
import { cleanupRateLimitCache, withRateLimit } from './utils/rateLimit';
// ─── Auto-run migration at startup ──────────────────────────────────────────
try {
const { runMigration } = await import('./db/migrate');
await runMigration();
} catch {
logger.warn('Auto-migration skipped (non-fatal)');
}
// ─── Auto-run migration at startup ───
try {
await import('./db/migrate');
} catch {
// migrate.ts calls process.exit(1) on failure — if it throws, log and continue
logger.warn('Auto-migration warning (non-fatal)');
}
const server = serve({
port: config.port,
routes: {