const { app, initializeApp } = require('./app'); const { closeConnection } = require('./config/database'); const { closeRedisConnection } = require('./config/redis'); const { closeQueues } = require('./config/bullmq'); const config = require('./config/config.json'); const PORT = config.server.port || 3000; const HOST = '0.0.0.0'; let server; /** * Start Server */ const startServer = async () => { try { // Initialize application (database, models, etc.) await initializeApp(); // Start Express server server = app.listen(PORT, HOST, () => { console.log(''); console.log('╔════════════════════════════════════════════════════════╗'); console.log('║ 🚀 Sena School Management API Server Started ║'); console.log('╠════════════════════════════════════════════════════════╣'); console.log(`║ Environment: ${config.server.env.padEnd(38)} ║`); console.log(`║ Server URL: http://${HOST}:${PORT}${' '.repeat(30 - HOST.length - PORT.toString().length)} ║`); console.log(`║ API Base: http://${HOST}:${PORT}/api${' '.repeat(25 - HOST.length - PORT.toString().length)} ║`); console.log(`║ Health: http://${HOST}:${PORT}/health${' '.repeat(22 - HOST.length - PORT.toString().length)} ║`); console.log('╠════════════════════════════════════════════════════════╣'); console.log('║ 📊 Services Status: ║'); console.log('║ ✅ MySQL Database Connected (senaai.tech:11001) ║'); console.log('║ ✅ Redis Sentinel Connected (senaai.tech) ║'); console.log('║ ✅ BullMQ Queues Initialized ║'); console.log('╚════════════════════════════════════════════════════════╝'); console.log(''); console.log('📝 Available Endpoints:'); console.log(` GET /health - Health check`); console.log(` GET /api - API information`); console.log(` GET /api/schools - List schools`); console.log(` POST /api/schools - Create school`); console.log(` GET /api/queues/status - Queue metrics`); console.log(` GET /api/cache/stats - Cache statistics`); console.log(''); console.log('🔧 To start the BullMQ worker:'); console.log(' node workers/databaseWriteWorker.js'); console.log(''); }); // Handle server errors server.on('error', (error) => { console.error('❌ Server error:', error.message); process.exit(1); }); } catch (error) { console.error('❌ Failed to start server:', error.message); process.exit(1); } }; /** * Graceful Shutdown */ const gracefulShutdown = async (signal) => { console.log(''); console.log(`⚠️ ${signal} received. Starting graceful shutdown...`); // Stop accepting new connections if (server) { server.close(async () => { console.log('✅ HTTP server closed'); try { // Close database connections await closeConnection(); // Close Redis connection await closeRedisConnection(); // Close BullMQ queues await closeQueues(); console.log('✅ All connections closed gracefully'); process.exit(0); } catch (error) { console.error('❌ Error during shutdown:', error.message); process.exit(1); } }); // Force close after 10 seconds setTimeout(() => { console.error('⚠️ Forcing shutdown after timeout'); process.exit(1); }, 10000); } else { process.exit(0); } }; /** * Handle Uncaught Exceptions */ process.on('uncaughtException', (error) => { console.error('💥 UNCAUGHT EXCEPTION! Shutting down...'); console.error(error.name, error.message); console.error(error.stack); process.exit(1); }); /** * Handle Unhandled Promise Rejections */ process.on('unhandledRejection', (error) => { console.error('💥 UNHANDLED REJECTION! Shutting down...'); console.error(error.name, error.message); gracefulShutdown('UNHANDLED_REJECTION'); }); /** * Handle Termination Signals */ process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); process.on('SIGINT', () => gracefulShutdown('SIGINT')); /** * Start the server */ startServer(); module.exports = { server };