import express from 'express'; import cors from 'cors'; import helmet from 'helmet'; import rateLimit from 'express-rate-limit'; import path from 'path'; import http from 'http'; import { Server as SocketServer } from 'socket.io'; import { config } from './config'; import { connectDatabase } from './config/database'; import { logger } from './utils/logger'; import { errorHandler } from './middleware/errorHandler'; import { setupMCPServer } from './services/mcpServer'; // Route imports import authRoutes from './routes/auth'; import projectRoutes from './routes/projects'; import videoRoutes from './routes/videos'; import presetRoutes from './routes/presets'; import assetRoutes from './routes/assets'; import adminRoutes from './routes/admin'; const app = express(); const server = http.createServer(app); // WebSocket server for CLI bridge const io = new SocketServer(server, { cors: { origin: ['http://localhost:5173', 'http://localhost:3000'], methods: ['GET', 'POST'], credentials: true, }, }); // Middleware app.use(helmet({ crossOriginResourcePolicy: { policy: 'cross-origin' } })); app.use(cors({ origin: ['http://localhost:5173', 'http://localhost:3000'], credentials: true, })); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); // Rate limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 200, message: { error: 'Too many requests, please try again later.' }, }); app.use('/api/', limiter); // Static files for uploads and generated content app.use('/uploads', express.static(path.resolve(config.upload.dir))); app.use('/generated', express.static(path.resolve(config.upload.generatedDir))); // API Routes app.use('/api/auth', authRoutes); app.use('/api/projects', projectRoutes); app.use('/api/videos', videoRoutes); app.use('/api/presets', presetRoutes); app.use('/api/assets', assetRoutes); app.use('/api/admin', adminRoutes); // Health check app.get('/api/health', (_req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // Error handler app.use(errorHandler); // Initialize MCP Server over WebSocket setupMCPServer(io); // Start server async function start(): Promise { try { await connectDatabase(); server.listen(config.port, () => { logger.info(`Director.AI server running on port ${config.port}`); logger.info(`WebSocket server ready for CLI bridge connections`); logger.info(`Environment: ${config.nodeEnv}`); }); } catch (error) { logger.error('Failed to start server:', error); process.exit(1); } } start();