diff --git a/backend/docker-entrypoint.sh b/backend/docker-entrypoint.sh index dc696e6..7f61fa6 100644 --- a/backend/docker-entrypoint.sh +++ b/backend/docker-entrypoint.sh @@ -1,32 +1,2 @@ #!/bin/sh -set -e - -echo "▶ NotesFrais backend — démarrage" - -# Attendre que PostgreSQL soit prêt (Coolify peut démarrer les conteneurs en parallèle) -MAX=30 -i=0 -until node -e " - const { Client } = require('pg'); - const c = new Client({ connectionString: process.env.DATABASE_URL }); - c.connect().then(() => { c.end(); process.exit(0); }).catch(() => process.exit(1)); -" 2>/dev/null; do - i=$((i+1)) - if [ $i -ge $MAX ]; then - echo "✗ PostgreSQL inaccessible après ${MAX} tentatives — abandon" - exit 1 - fi - echo " PostgreSQL non prêt, attente (${i}/${MAX})…" - sleep 2 -done - -echo "✓ PostgreSQL prêt" - -# Migration (idempotente — IF NOT EXISTS sur toutes les créations) -echo "▶ Migration de la base de données…" -node dist/scripts/migrate.js -echo "✓ Migration terminée" - -# Démarrage du serveur -echo "▶ Démarrage du serveur Express sur le port ${PORT:-3001}" exec node dist/index.js diff --git a/backend/src/index.ts b/backend/src/index.ts index ffc12d6..9869acb 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -4,8 +4,9 @@ import cors from 'cors'; import helmet from 'helmet'; import path from 'path'; import fs from 'fs'; +import { Pool } from 'pg'; import { config } from './config'; -import { testConnection } from './db'; +import { db, testConnection } from './db'; // Routes import authRoutes from './routes/auth'; @@ -40,16 +41,36 @@ app.get('/api/health', (_req, res) => res.json({ status: 'ok', version: '1.0.0', // ─── Gestionnaire d'erreurs global ──────────────────────────── app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => { console.error('[Error]', err.stack); - // Include error message always (for debug) — revert to 'Erreur serveur interne' in production once stable res.status(500).json({ error: err.message, type: err.constructor.name, }); }); +// ─── Initialisation DB + migration (arrière-plan) ───────────── +async function runMigration(): Promise { + const sqlPath = path.join(__dirname, 'migrations/001_init.sql'); + const sql = fs.readFileSync(sqlPath, 'utf8'); + await db.query(sql); + console.log('✅ Migration terminée'); +} + +async function waitForDb(maxAttempts = 30, delayMs = 2000): Promise { + for (let i = 1; i <= maxAttempts; i++) { + try { + await testConnection(); + return; + } catch { + console.log(` PostgreSQL non prêt (${i}/${maxAttempts}), attente...`); + await new Promise(r => setTimeout(r, delayMs)); + } + } + throw new Error(`PostgreSQL inaccessible après ${maxAttempts} tentatives`); +} + // ─── Démarrage ──────────────────────────────────────────────── async function start() { - // Créer les répertoires uploads (ici pour éviter un crash module-level) + // Créer les répertoires uploads try { fs.mkdirSync(path.join(config.uploadsDir, 'images'), { recursive: true }); fs.mkdirSync(path.join(config.uploadsDir, 'pdfs'), { recursive: true }); @@ -57,7 +78,32 @@ async function start() { console.warn('Avertissement: impossible de créer les répertoires uploads:', err.message); } - app.listen(config.port, async () => { + // ── Bind du port IMMÉDIATEMENT ───────────────────────────── + app.listen(config.port, () => { console.log(`🚀 NotesFrais backend démarré sur le port ${config.port}`); console.log(` Environnement : ${config.nodeEnv}`); - console.log(` Frontend autorisé : ${ \ No newline at end of file + console.log(` Frontend autorisé : ${config.frontendUrl}`); + console.log(` DATABASE_URL: ${process.env.DATABASE_URL + ? process.env.DATABASE_URL.replace(/:([^@]+)@/, ':***@') + : '[non défini — utilise défaut localhost]'}`); + }); + + // ── Initialisation DB en arrière-plan ───────────────────── + (async () => { + try { + await waitForDb(); + await runMigration(); + console.log('✅ Base de données prête'); + } catch (err: any) { + console.error('⚠️ Initialisation DB échouée (non bloquant):', err.message); + // Le serveur continue — les routes retourneront des 500 si la DB est inaccessible + } + })(); +} + +start().catch((err) => { + console.error('Impossible de démarrer le serveur :', err.message); + process.exit(1); +}); + +export default app;