69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
/**
|
|
* @ai-summary Application entry point
|
|
* @ai-context Starts the Fastify server with all feature capsules
|
|
*/
|
|
import { buildApp } from './app';
|
|
import { appConfig } from './core/config/config-loader';
|
|
import { logger } from './core/logging/logger';
|
|
import { initializeScheduler } from './core/scheduler';
|
|
import { pool } from './core/config/database';
|
|
import { CatalogSeedService } from './features/platform/domain/catalog-seed.service';
|
|
|
|
const PORT = appConfig.config.server.port;
|
|
|
|
async function start() {
|
|
try {
|
|
const app = await buildApp();
|
|
|
|
// Seed vehicle catalog data if needed (runs after migrations)
|
|
try {
|
|
const catalogSeedService = new CatalogSeedService(pool);
|
|
await catalogSeedService.seedIfEmpty();
|
|
} catch (seedError) {
|
|
logger.warn('Vehicle catalog seeding failed, continuing startup', { seedError });
|
|
// Continue startup even if seeding fails (data can be imported later via admin UI)
|
|
}
|
|
|
|
await app.listen({
|
|
port: PORT,
|
|
host: '0.0.0.0'
|
|
});
|
|
|
|
logger.info(`MotoVaultPro backend running`, {
|
|
port: PORT,
|
|
environment: appConfig.config.server.environment,
|
|
nodeVersion: process.version,
|
|
framework: 'Fastify'
|
|
});
|
|
|
|
// Initialize cron scheduler for background tasks
|
|
initializeScheduler();
|
|
} catch (error) {
|
|
logger.error('Failed to start server', { error });
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
start();
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGTERM', () => {
|
|
logger.info('SIGTERM received, shutting down gracefully');
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on('SIGINT', () => {
|
|
logger.info('SIGINT received, shutting down gracefully');
|
|
process.exit(0);
|
|
});
|
|
|
|
// Handle uncaught exceptions
|
|
process.on('uncaughtException', (error) => {
|
|
logger.error('Uncaught Exception', { error: error.message, stack: error.stack });
|
|
process.exit(1);
|
|
});
|
|
|
|
process.on('unhandledRejection', (reason, promise) => {
|
|
logger.error('Unhandled Rejection', { reason, promise });
|
|
process.exit(1);
|
|
}); |