import express from 'express'; import cors from 'cors'; import helmet from 'helmet'; import morgan from 'morgan'; import rateLimit from 'express-rate-limit'; import path from 'path'; import config from './config'; import logger from './config/logger'; import { connectDB } from './config/database'; import routes from './routes'; import { errorHandler, notFoundHandler } from './middleware/errorHandler'; const app = express(); // Crear directorio de logs si no existe const fs = require('fs'); const logsDir = path.join(__dirname, '../logs'); if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir); } // Middleware de seguridad app.use(helmet()); // CORS app.use(cors({ origin: config.FRONTEND_URL, credentials: true, })); // Rate limiting const limiter = rateLimit({ windowMs: config.RATE_LIMIT.WINDOW_MS, max: config.RATE_LIMIT.MAX_REQUESTS, message: { success: false, message: 'Demasiadas peticiones, por favor intenta más tarde', }, }); app.use('/api/', limiter); // Logging HTTP app.use(morgan('combined', { stream: { write: (message: string) => logger.info(message.trim()), }, })); // Parsing de body app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); // Rutas API app.use('/api/v1', routes); // Ruta raíz app.get('/', (_req, res) => { res.json({ success: true, message: '🎾 API de Canchas de Pádel', version: '1.0.0', docs: '/api/v1/health', }); }); // Handler de rutas no encontradas app.use(notFoundHandler); // Handler de errores global app.use(errorHandler); // Conectar a BD y iniciar servidor const startServer = async () => { try { // Conectar a base de datos await connectDB(); // Iniciar servidor app.listen(config.PORT, () => { logger.info(`🚀 Servidor corriendo en http://localhost:${config.PORT}`); logger.info(`📚 API disponible en http://localhost:${config.PORT}/api/v1`); logger.info(`🏥 Health check: http://localhost:${config.PORT}/api/v1/health`); }); } catch (error) { logger.error('Error al iniciar el servidor:', error); process.exit(1); } }; // Manejo de errores no capturados process.on('uncaughtException', (error) => { logger.error('Uncaught Exception:', error); process.exit(1); }); process.on('unhandledRejection', (reason) => { logger.error('Unhandled Rejection:', reason); process.exit(1); }); // Graceful shutdown process.on('SIGTERM', async () => { logger.info('SIGTERM recibido, cerrando servidor...'); process.exit(0); }); process.on('SIGINT', async () => { logger.info('SIGINT recibido, cerrando servidor...'); process.exit(0); }); // Iniciar startServer(); export default app;