/** * Tractatus Express Server * Main application entry point */ require('dotenv').config(); const express = require('express'); const helmet = require('helmet'); const cors = require('cors'); const rateLimit = require('express-rate-limit'); const config = require('./config/app.config'); const logger = require('./utils/logger.util'); const { connect: connectDb, close: closeDb } = require('./utils/db.util'); const { notFound, errorHandler } = require('./middleware/error.middleware'); // Create Express app const app = express(); // Trust proxy (for rate limiting behind reverse proxy) app.set('trust proxy', 1); // Security middleware app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], scriptSrc: ["'self'"], imgSrc: ["'self'", "data:", "https:"], }, }, })); // CORS app.use(cors(config.cors)); // Body parsers app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); // Request logging app.use(logger.request); // Rate limiting const limiter = rateLimit({ windowMs: config.security.rateLimitWindowMs, max: config.security.rateLimitMaxRequests, message: 'Too many requests from this IP, please try again later', standardHeaders: true, legacyHeaders: false, }); app.use('/api/', limiter); // Static files app.use(express.static('public')); // Health check endpoint app.get('/health', (req, res) => { res.json({ status: 'healthy', timestamp: new Date().toISOString(), uptime: process.uptime(), environment: config.env }); }); // API routes const apiRoutes = require('./routes/index'); app.use('/api', apiRoutes); // Homepage (temporary) app.get('/', (req, res) => { res.send(`
✓ Server Running
Development environment for the Tractatus-Based LLM Safety Framework website.
GET /health - Health checkGET /api - API documentationPOST /api/auth/login - Admin loginGET /api/documents - List framework documentsGET /api/blog - List published blog postsGET /api/admin/stats - System statistics (auth required)Phase 1 Development - Not for public use
`); }); // 404 handler app.use(notFound); // Error handler app.use(errorHandler); // Server startup async function start() { try { // Connect to MongoDB await connectDb(); // Start server const server = app.listen(config.port, () => { logger.info(`🚀 Tractatus server started`); logger.info(`✅ Environment: ${config.env}`); logger.info(`✅ Port: ${config.port}`); logger.info(`✅ MongoDB: ${config.mongodb.db}`); logger.info(`✨ Ready for development`); console.log(`\n🌐 http://localhost:${config.port}\n`); }); // Graceful shutdown process.on('SIGTERM', () => shutdown(server)); process.on('SIGINT', () => shutdown(server)); } catch (error) { logger.error('Failed to start server:', error); process.exit(1); } } // Graceful shutdown async function shutdown(server) { logger.info('Shutting down gracefully...'); server.close(async () => { logger.info('HTTP server closed'); await closeDb(); logger.info('Database connection closed'); process.exit(0); }); // Force shutdown after 10 seconds setTimeout(() => { logger.error('Forced shutdown after timeout'); process.exit(1); }, 10000); } // Start server if run directly if (require.main === module) { start(); } module.exports = app;