const express = require('express'); const cors = require('cors'); const helmet = require('helmet'); const compression = require('compression'); const morgan = require('morgan'); const rateLimit = require('express-rate-limit'); const { createServer } = require('http'); const { Server } = require('socket.io'); require('dotenv').config(); const logger = require('./utils/logger'); const database = require('./config/database'); const redis = require('./config/redis'); const socketHandler = require('./socket/socketHandler'); const errorHandler = require('./middleware/errorHandler'); // Import routes const authRoutes = require('./routes/auth'); const deviceRoutes = require('./routes/devices'); const alertRoutes = require('./routes/alerts'); const analyticsRoutes = require('./routes/analytics'); const healingRoutes = require('./routes/healing'); const suggestionsRoutes = require('./routes/suggestions'); const notificationsRoutes = require('./routes/notifications'); const streamPipesRoutes = require('./routes/streamPipes'); // Import services const streamPipesService = require('./services/streamPipesService'); const aiAgentService = require('./services/aiAgentService'); const alertService = require('./services/alertService'); const healingService = require('./services/healingService'); const app = express(); const server = createServer(app); const io = new Server(server, { cors: { origin: process.env.CORS_ORIGIN || "http://localhost:3000", methods: ["GET", "POST"] } }); // Rate limiting const limiter = rateLimit({ windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100, // limit each IP to 100 requests per windowMs message: 'Too many requests from this IP, please try again later.' }); // Middleware app.use(helmet()); app.use(compression()); app.use(cors({ origin: process.env.CORS_ORIGIN || "http://localhost:3000", credentials: true })); app.use(limiter); app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } })); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); // Health check endpoint app.get('/health', (req, res) => { res.status(200).json({ status: 'OK', timestamp: new Date().toISOString(), uptime: process.uptime(), environment: process.env.NODE_ENV }); }); // API Routes app.use('/api/auth', authRoutes); app.use('/api/devices', deviceRoutes); app.use('/api/alerts', alertRoutes); app.use('/api/analytics', analyticsRoutes); app.use('/api/healing', healingRoutes); app.use('/api/suggestions', suggestionsRoutes); app.use('/api/notifications', notificationsRoutes); app.use('/api/streampipes', streamPipesRoutes); // Socket.io connection handling socketHandler(io); // Error handling middleware app.use(errorHandler); // 404 handler app.use('*', (req, res) => { res.status(404).json({ success: false, message: 'Route not found' }); }); const PORT = process.env.PORT || 5000; // Initialize services async function initializeServices() { try { // Initialize database connection await database.connect(); logger.info('Database connected successfully'); // Initialize Redis connection await redis.connect(); logger.info('Redis connected successfully'); // Initialize StreamPipes service try { await streamPipesService.initialize(); logger.info('StreamPipes service initialized'); } catch (error) { logger.warn('StreamPipes service initialization failed - continuing without it'); } // Initialize AI Agent service try { await aiAgentService.initialize(); logger.info('AI Agent service initialized'); } catch (error) { logger.warn('AI Agent service initialization failed - continuing without it'); } // Initialize Alert service try { await alertService.initialize(); logger.info('Alert service initialized'); } catch (error) { logger.warn('Alert service initialization failed - continuing without it'); } // Initialize Healing service try { await healingService.initialize(); logger.info('Healing service initialized'); } catch (error) { logger.warn('Healing service initialization failed - continuing without it'); } // Start the server server.listen(PORT, () => { logger.info(`AI Agent Backend server running on port ${PORT}`); logger.info(`Environment: ${process.env.NODE_ENV}`); }); } catch (error) { logger.error('Failed to initialize services:', error); process.exit(1); } } // Graceful shutdown process.on('SIGTERM', async () => { logger.info('SIGTERM received, shutting down gracefully'); await database.disconnect(); await redis.disconnect(); server.close(() => { logger.info('Server closed'); process.exit(0); }); }); process.on('SIGINT', async () => { logger.info('SIGINT received, shutting down gracefully'); await database.disconnect(); await redis.disconnect(); server.close(() => { logger.info('Server closed'); process.exit(0); }); }); // Handle unhandled promise rejections process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled Rejection at:', promise, 'reason:', reason); }); // Handle uncaught exceptions process.on('uncaughtException', (error) => { logger.error('Uncaught Exception:', error); process.exit(1); }); // Start the application initializeServices();