import express, { Application, Request, Response, NextFunction } from 'express'; import cors from 'cors'; import helmet from 'helmet'; import rateLimit from 'express-rate-limit'; import dotenv from 'dotenv'; import { PrismaClient } from '@prisma/client'; // Import routes import authRoutes from './routes/auth'; import clientRoutes from './routes/clients'; import commissionRoutes from './routes/commissions'; import policyRoutes from './routes/policies'; import todoRoutes from './routes/todos'; import documentRoutes from './routes/documents'; import reportRoutes from './routes/reports'; import auditRoutes from './routes/audit'; import notificationRoutes from './routes/notifications'; // Import middleware import { errorHandler } from './middleware/errorHandler'; import { authMiddleware } from './middleware/auth'; import { auditMiddleware } from './middleware/audit'; import { requestLogger } from './middleware/logger'; // Load environment variables dotenv.config(); // Initialize Express app const app: Application = express(); const PORT = process.env.PORT || 3001; // Initialize Prisma client export const prisma = new PrismaClient({ log: process.env.NODE_ENV === 'development' ? ['query', 'info', 'warn', 'error'] : ['error'], }); // Security middleware app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], scriptSrc: ["'self'"], imgSrc: ["'self'", "data:", "https:"], }, }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true, }, })); // CORS configuration app.use(cors({ origin: process.env.FRONTEND_URL || 'http://localhost:5173', credentials: true, methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'], })); // Rate limiting const limiter = rateLimit({ windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000'), max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS || '100'), message: 'Too many requests from this IP, please try again later.', standardHeaders: true, legacyHeaders: false, }); app.use(limiter); // Stricter rate limiting for auth endpoints const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5, // 5 attempts message: 'Too many authentication attempts, please try again later.', }); // Body parsing middleware app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); // Request logging app.use(requestLogger); // Health check endpoint (no auth required) app.get('/health', (req: Request, res: Response) => { res.status(200).json({ status: 'healthy', timestamp: new Date().toISOString(), version: '1.0.0', environment: process.env.NODE_ENV, }); }); // API routes app.use('/api/auth', authLimiter, authRoutes); // Protected routes (require authentication) app.use('/api/clients', authMiddleware, auditMiddleware, clientRoutes); app.use('/api/commissions', authMiddleware, auditMiddleware, commissionRoutes); app.use('/api/policies', authMiddleware, auditMiddleware, policyRoutes); app.use('/api/todos', authMiddleware, auditMiddleware, todoRoutes); app.use('/api/documents', authMiddleware, auditMiddleware, documentRoutes); app.use('/api/reports', authMiddleware, auditMiddleware, reportRoutes); app.use('/api/audit', authMiddleware, auditRoutes); app.use('/api/notifications', authMiddleware, notificationRoutes); // 404 handler app.use((req: Request, res: Response) => { res.status(404).json({ success: false, message: 'Route not found', path: req.path, }); }); // Global error handler app.use(errorHandler); // Graceful shutdown process.on('SIGTERM', async () => { console.log('SIGTERM received, shutting down gracefully'); await prisma.$disconnect(); process.exit(0); }); process.on('SIGINT', async () => { console.log('SIGINT received, shutting down gracefully'); await prisma.$disconnect(); process.exit(0); }); // Start server app.listen(PORT, () => { console.log(`🚀 InsureCRM Pro Backend Server running on port ${PORT}`); console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`); console.log(`🔒 Security: Helmet enabled, Rate limiting enabled`); console.log(`📝 Audit logging: Active`); }); export default app;