import express from "express"; import cors from "cors"; import helmet from "helmet"; import morgan from "morgan"; import client from "prom-client"; import config from "./src/config/env.js"; import { pool } from "./db.js"; import { errorHandler } from "./src/middleware/errorHandler.js"; import { metricsMiddleware } from "./src/middleware/metrics.js"; // Import routes import authRoutes from "./src/routes/auth.routes.js"; import userRoutes from "./src/routes/user.routes.js"; import gameRoutes from "./src/routes/game.routes.js"; import employeeRoutes from "./src/routes/employee.routes.js"; import adminRoutes from "./src/routes/admin.routes.js"; import drawRoutes from "./src/routes/draw.routes.js"; import newsletterRoutes from "./src/routes/newsletter.routes.js"; import contactRoutes from "./src/routes/contact.routes.js"; const app = express(); // CORS doit être configuré AVANT helmet app.use( cors({ origin: function (origin, callback) { const allowedOrigins = [ "http://localhost:3000", "http://localhost:3001", "http://localhost:3002", "http://localhost:3003", "http://localhost:3004", "http://localhost:3005", "https://dsp5-archi-o24a-15m-g3.fr", "https://dev.dsp5-archi-o24a-15m-g3.fr" ]; // Autoriser les requêtes sans origin (Postman, curl, etc.) if (!origin) return callback(null, true); if (allowedOrigins.indexOf(origin) !== -1) { callback(null, true); } else { callback(null, true); // En dev, on autorise tout } }, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'], exposedHeaders: ['Content-Length', 'X-Request-Id'], maxAge: 86400, // 24h }) ); // Helmet avec configuration moins restrictive app.use(helmet({ crossOriginResourcePolicy: { policy: "cross-origin" }, crossOriginOpenerPolicy: { policy: "same-origin-allow-popups" }, })); app.use(morgan("tiny")); app.use(express.json()); // Middleware de métriques HTTP (doit être avant les routes) app.use(metricsMiddleware); // Servir les fichiers statiques depuis le dossier public app.use('/public', express.static('public')); // ✅ Route racine (pour test ou monitoring) app.get("/", (req, res) => { res.status(200).json({ message: "✅ API The Tip Top en ligne et opérationnelle -branche dev- !" }); }); // Vérif base de données app.get("/db-check", async (req, res) => { try { const result = await pool.query("SELECT NOW()"); res.json({ message: "✅ DB connectée branche dev", time: result.rows[0].now }); } catch (err) { res.status(500).json({ error: err.message }); } }); // Prometheus const collectDefaultMetrics = client.collectDefaultMetrics; collectDefaultMetrics(); app.get("/metrics", async (req, res) => { res.set("Content-Type", client.register.contentType); res.end(await client.register.metrics()); }); // API Routes app.use("/api/auth", authRoutes); app.use("/api/users", userRoutes); app.use("/api/game", gameRoutes); app.use("/api/employee", employeeRoutes); app.use("/api/admin", adminRoutes); app.use("/api/draw", drawRoutes); app.use("/api/newsletter", newsletterRoutes); app.use("/api/contact", contactRoutes); // Error handler (doit être après les routes) app.use(errorHandler); // Export app for testing export default app; // Lancement serveur (seulement si pas importé par les tests) if (process.env.NODE_ENV !== 'test') { const PORT = config.server.port; app.listen(PORT, "0.0.0.0", () => { console.log(`🚀 Backend lancé sur 0.0.0.0:${PORT} ✅`); }); }