- PostgreSQL 17 + TimescaleDB schema with 12 tables - 48 standards (IEEE, SFF, ITU-T, OIF, MSA) - 33 form factors (SFP through OSFP-XD/CPO) - 85+ vendors (OEM, compatible, manufacturers, marketplaces) - 80+ seed transceivers (1G-1.6T, CWDM, BiDi, DAC, AOC, FC, PON) - 60+ network devices (Cisco, Juniper, Arista, HPE, Dell, etc.) - Crawler framework with fs.com and eBay crawlers - REST API (15 endpoints) on port 3200 - MCP server (12 tools) on port 3201 - PM2 ecosystem for production deployment on Erik (.82)
56 lines
1.4 KiB
TypeScript
56 lines
1.4 KiB
TypeScript
import 'dotenv/config';
|
|
import { readFileSync, readdirSync } from 'fs';
|
|
import { join } from 'path';
|
|
import { query, pool } from '../src/utils/db.js';
|
|
import { pino } from 'pino';
|
|
|
|
const log = pino({ name: 'migrate' });
|
|
|
|
async function main() {
|
|
log.info('Running migrations...');
|
|
|
|
// Create migrations tracking table
|
|
await query(`
|
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(200) NOT NULL UNIQUE,
|
|
applied_at TIMESTAMPTZ DEFAULT NOW()
|
|
)
|
|
`);
|
|
|
|
// Get applied migrations
|
|
const applied = await query('SELECT name FROM _migrations ORDER BY id');
|
|
const appliedSet = new Set(applied.rows.map(r => r.name));
|
|
|
|
// Read migration files
|
|
const migrationsDir = join(import.meta.dirname ?? '.', '..', 'migrations');
|
|
const files = readdirSync(migrationsDir)
|
|
.filter(f => f.endsWith('.sql'))
|
|
.sort();
|
|
|
|
for (const file of files) {
|
|
if (appliedSet.has(file)) {
|
|
log.info(`Skip (already applied): ${file}`);
|
|
continue;
|
|
}
|
|
|
|
log.info(`Applying: ${file}`);
|
|
const sql = readFileSync(join(migrationsDir, file), 'utf-8');
|
|
|
|
try {
|
|
await query(sql);
|
|
await query('INSERT INTO _migrations (name) VALUES ($1)', [file]);
|
|
log.info(`Applied: ${file}`);
|
|
} catch (err) {
|
|
log.error({ err, file }, 'Migration failed');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
log.info('All migrations applied');
|
|
await pool.end();
|
|
process.exit(0);
|
|
}
|
|
|
|
main();
|