const path = require('path'); const fs = require('fs'); const express = require('express'); const mysql = require('mysql2/promise'); const { corsMiddleware, corsErrorHandler } = require('./middleware/cors'); const { initPool } = require('./utils/db'); const productsRouter = require('./routes/products'); const dashboardRouter = require('./routes/dashboard'); const ordersRouter = require('./routes/orders'); const csvRouter = require('./routes/csv'); const analyticsRouter = require('./routes/analytics'); // Get the absolute path to the .env file const envPath = path.resolve(process.cwd(), '.env'); console.log('Current working directory:', process.cwd()); console.log('Looking for .env file at:', envPath); console.log('.env file exists:', fs.existsSync(envPath)); try { require('dotenv').config({ path: envPath }); console.log('.env file loaded successfully'); console.log('Environment check:', { NODE_ENV: process.env.NODE_ENV || 'not set', PORT: process.env.PORT || 'not set', DB_HOST: process.env.DB_HOST || 'not set', DB_USER: process.env.DB_USER || 'not set', DB_NAME: process.env.DB_NAME || 'not set', }); } catch (error) { console.error('Error loading .env file:', error); } // Ensure required directories exist ['logs', 'uploads'].forEach(dir => { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } }); const app = express(); // Debug middleware to log request details app.use((req, res, next) => { console.log('Request details:', { method: req.method, url: req.url, origin: req.get('Origin'), headers: req.headers }); next(); }); // Apply CORS middleware first, before any other middleware app.use(corsMiddleware); // Body parser middleware app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Initialize database pool const pool = initPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, waitForConnections: true, connectionLimit: process.env.NODE_ENV === 'production' ? 20 : 10, queueLimit: 0, enableKeepAlive: true, keepAliveInitialDelay: 0 }); // Make pool available to routes app.locals.pool = pool; // Routes app.use('/api/products', productsRouter); app.use('/api/dashboard', dashboardRouter); app.use('/api/orders', ordersRouter); app.use('/api/csv', csvRouter); app.use('/api/analytics', analyticsRouter); // Basic health check route app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString(), environment: process.env.NODE_ENV }); }); // CORS error handler - must be before other error handlers app.use(corsErrorHandler); // Error handling middleware - MUST be after routes and CORS error handler app.use((err, req, res, next) => { console.error(`[${new Date().toISOString()}] Error:`, err); // Send detailed error in development, generic in production const error = process.env.NODE_ENV === 'production' ? 'An internal server error occurred' : err.message || err; res.status(err.status || 500).json({ error }); }); // Handle uncaught exceptions process.on('uncaughtException', (err) => { console.error(`[${new Date().toISOString()}] Uncaught Exception:`, err); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error(`[${new Date().toISOString()}] Unhandled Rejection at:`, promise, 'reason:', reason); }); // Test database connection pool.getConnection() .then(connection => { console.log('[Database] Connected successfully'); connection.release(); }) .catch(err => { console.error('[Database] Error connecting:', err); process.exit(1); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`[Server] Running in ${process.env.NODE_ENV || 'development'} mode on port ${PORT}`); });