import dotenv from 'dotenv'; dotenv.config(); import express, { Application, Request, Response, NextFunction } from 'express'; import cors from 'cors'; import helmet from 'helmet'; import routes from './routes'; import logger from './utils/logger'; import { testConnection } from './config/database'; import { auditMiddleware } from './middleware/audit.middleware'; import { scheduleNegativeFlowDetection } from './jobs/negativeFlowDetection'; const app: Application = express(); const PORT = process.env.PORT || 3000; const NODE_ENV = process.env.NODE_ENV || 'development'; // Security middleware app.use(helmet()); // CORS configuration const allowedOrigins = (process.env.CORS_ORIGIN || 'http://localhost:5173') .split(',') .map(origin => origin.trim()); app.use(cors({ origin: (origin, callback) => { // Allow requests with no origin (mobile apps, curl, etc.) if (!origin) return callback(null, true); if (allowedOrigins.includes(origin)) { callback(null, true); } else { logger.warn(`CORS blocked origin: ${origin}`); callback(null, true); // Allow all in development } }, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'] })); // Body parsing middleware app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); // Audit logging middleware (before routes) app.use(auditMiddleware); // Health check endpoint app.get('/health', (_req: Request, res: Response) => { res.status(200).json({ status: 'ok', timestamp: new Date().toISOString(), environment: NODE_ENV }); }); // Mount all API routes app.use('/api', routes); // 404 handler app.use((_req: Request, res: Response) => { res.status(404).json({ success: false, message: 'Resource not found', error: 'NOT_FOUND' }); }); // Global error handler app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => { console.error('Error:', err); res.status(500).json({ success: false, message: NODE_ENV === 'development' ? err.message : 'Internal server error', error: 'INTERNAL_ERROR' }); }); // Start server const startServer = async () => { try { // Test database connection await testConnection(); logger.info('Database connection established'); scheduleNegativeFlowDetection(); logger.info('Cron jobs initialized'); app.listen(PORT, () => { logger.info(`Server running on port ${PORT} in ${NODE_ENV} mode`); logger.info(`Health check available at http://localhost:${PORT}/health`); logger.info(`API available at http://localhost:${PORT}/api`); }); } catch (error) { logger.error('Failed to start server:', error); process.exit(1); } }; startServer(); export default app;