133 lines
3.9 KiB
JavaScript
133 lines
3.9 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const { Client } = require('pg');
|
|
const { DataSource } = require('typeorm');
|
|
const path = require('path');
|
|
const { spawn } = require('child_process');
|
|
const { existsSync } = require('fs');
|
|
// Docker copies this script to /app/startup.js; local copies stay in scripts/setup.
|
|
const applicationRoot = existsSync(path.join(__dirname, 'dist'))
|
|
? __dirname
|
|
: path.resolve(__dirname, '../..');
|
|
const { databaseTlsOptions } = require(
|
|
path.join(applicationRoot, 'dist/infrastructure/persistence/typeorm/database-tls')
|
|
);
|
|
const { SafeDatabaseLogger } = require(
|
|
path.join(applicationRoot, 'dist/infrastructure/persistence/typeorm/safe-database-logger')
|
|
);
|
|
|
|
async function waitForPostgres(maxAttempts = 30) {
|
|
console.log('⏳ Waiting for PostgreSQL to be ready...');
|
|
|
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
try {
|
|
const client = new Client({
|
|
host: process.env.DATABASE_HOST,
|
|
port: parseInt(process.env.DATABASE_PORT, 10),
|
|
user: process.env.DATABASE_USER,
|
|
password: process.env.DATABASE_PASSWORD,
|
|
database: process.env.DATABASE_NAME,
|
|
ssl: databaseTlsOptions(
|
|
process.env.DATABASE_SSL,
|
|
process.env.DATABASE_SSL_CA,
|
|
process.env.DATABASE_HOST
|
|
),
|
|
});
|
|
|
|
await client.connect();
|
|
await client.end();
|
|
console.log('✅ PostgreSQL is ready');
|
|
return true;
|
|
} catch (error) {
|
|
console.log(`⏳ Attempt ${attempt}/${maxAttempts} - PostgreSQL not ready, retrying...`);
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
}
|
|
}
|
|
|
|
console.error('❌ Failed to connect to PostgreSQL after', maxAttempts, 'attempts');
|
|
process.exit(1);
|
|
}
|
|
|
|
async function runMigrations() {
|
|
console.log('🔄 Running database migrations...');
|
|
|
|
const AppDataSource = new DataSource({
|
|
type: 'postgres',
|
|
host: process.env.DATABASE_HOST,
|
|
port: parseInt(process.env.DATABASE_PORT, 10),
|
|
username: process.env.DATABASE_USER,
|
|
password: process.env.DATABASE_PASSWORD,
|
|
database: process.env.DATABASE_NAME,
|
|
ssl: databaseTlsOptions(
|
|
process.env.DATABASE_SSL,
|
|
process.env.DATABASE_SSL_CA,
|
|
process.env.DATABASE_HOST
|
|
),
|
|
entities: [path.join(applicationRoot, 'dist/**/*.orm-entity.js')],
|
|
migrations: [
|
|
path.join(applicationRoot, 'dist/infrastructure/persistence/typeorm/migrations/*.js'),
|
|
],
|
|
synchronize: false,
|
|
logging: true,
|
|
logger: new SafeDatabaseLogger(true),
|
|
migrationsTransactionMode: 'all',
|
|
});
|
|
|
|
try {
|
|
await AppDataSource.initialize();
|
|
console.log('✅ DataSource initialized');
|
|
|
|
const migrations = await AppDataSource.runMigrations();
|
|
|
|
if (migrations.length === 0) {
|
|
console.log('✅ No pending migrations');
|
|
} else {
|
|
console.log(`✅ Successfully ran ${migrations.length} migration(s):`);
|
|
migrations.forEach(migration => {
|
|
console.log(` - ${migration.name}`);
|
|
});
|
|
}
|
|
|
|
await AppDataSource.destroy();
|
|
console.log('✅ Database migrations completed');
|
|
return true;
|
|
} catch (error) {
|
|
console.error('❌ Migration failed. Check migration prerequisites and database availability.');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
function startApplication() {
|
|
console.log('🚀 Starting NestJS application...');
|
|
|
|
const app = spawn('node', ['dist/main'], {
|
|
stdio: 'inherit',
|
|
env: process.env,
|
|
cwd: applicationRoot,
|
|
});
|
|
|
|
app.on('exit', code => {
|
|
process.exit(code);
|
|
});
|
|
|
|
process.on('SIGTERM', () => app.kill('SIGTERM'));
|
|
process.on('SIGINT', () => app.kill('SIGINT'));
|
|
}
|
|
|
|
async function main() {
|
|
console.log('🚀 Starting Xpeditis Backend...');
|
|
|
|
await waitForPostgres();
|
|
await runMigrations();
|
|
startApplication();
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main().catch(error => {
|
|
console.error('❌ Startup failed. Check migration prerequisites and database availability.');
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
module.exports = { waitForPostgres, runMigrations };
|