/** * @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); });