const express = require('express'); const cors = require('cors'); const helmet = require('helmet'); const morgan = require('morgan'); const compression = require('compression'); const rateLimit = require('express-rate-limit'); const { createServer } = require('http'); const { Server } = require('socket.io'); require('dotenv').config(); const { sequelize } = require('./models'); const routes = require('./routes'); const { initializeSocketHandlers } = require('./services/socketService'); const errorHandler = require('./middleware/errorHandler'); const app = express(); const server = createServer(app); const io = new Server(server, { cors: { origin: process.env.CORS_ORIGIN || "http://localhost:3000", methods: ["GET", "POST", "PUT", "DELETE"] } }); // 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, message: 'Too many requests from this IP, please try again later.' }); // Middleware app.use(helmet()); app.use(compression()); app.use(morgan('combined')); app.use(cors({ origin: process.env.CORS_ORIGIN || "http://localhost:3000", credentials: true })); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); app.use('/api/', limiter); // Make io available to routes app.use((req, res, next) => { req.io = io; next(); }); // Routes app.use('/api', routes); // Health check endpoints app.get('/health', (req, res) => { res.status(200).json({ status: 'OK', timestamp: new Date().toISOString(), environment: process.env.NODE_ENV }); }); app.use('/api/health', require('./routes/health')); // Error handling app.use(errorHandler); // Socket.IO initialization initializeSocketHandlers(io); const PORT = process.env.PORT || 3001; // Database connection and server startup async function startServer() { try { await sequelize.authenticate(); console.log('Database connected successfully.'); if (process.env.NODE_ENV !== 'production') { await sequelize.sync({ alter: true }); console.log('Database synchronized.'); } server.listen(PORT, () => { console.log(`Server running on port ${PORT}`); console.log(`Environment: ${process.env.NODE_ENV}`); }); } catch (error) { console.error('Unable to start server:', error); process.exit(1); } } startServer(); module.exports = { app, server, io };