NeahStable/PRODUCTION_FIXES_APPLIED.md
2026-01-16 18:22:20 +01:00

8.0 KiB

Corrections Appliquées pour la Production

Ce document liste les corrections critiques appliquées suite à l'analyse de performance et de préparation à la production.

Corrections Appliquées

1. Utilitaire fetchWithTimeout

Fichier créé: lib/utils/fetch-with-timeout.ts

Problème résolu: Requêtes HTTP sans timeout pouvant bloquer indéfiniment.

Utilisation:

import { fetchWithTimeout, fetchJsonWithTimeout } from '@/lib/utils/fetch-with-timeout';

// Exemple 1: Fetch simple avec timeout
const response = await fetchWithTimeout('https://api.example.com/data', {
  method: 'GET',
  timeout: 10000, // 10 secondes
  headers: { 'Authorization': 'Bearer token' }
});

// Exemple 2: Fetch avec parsing JSON automatique
const data = await fetchJsonWithTimeout<MyType>('https://api.example.com/data', {
  method: 'POST',
  timeout: 30000, // 30 secondes
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload)
});

Migration recommandée: Remplacer tous les fetch() dans:

  • lib/services/n8n-service.ts
  • app/api/missions/[missionId]/generate-plan/route.ts
  • app/api/users/[userId]/route.ts
  • app/api/leantime/tasks/route.ts
  • app/api/rocket-chat/messages/route.ts

2. Correction Dockerfile

Fichier modifié: Dockerfile

Problème résolu: Utilisation de migrate dev en production (créerait de nouvelles migrations).

Changement:

# ❌ AVANT
RUN npx prisma migrate dev --name init

# ✅ APRÈS
# NOTE: Migrations should be run separately before deployment
# DO NOT use 'migrate dev' in production
# Use 'prisma migrate deploy' instead, run separately before container start

Action requise: Utiliser Dockerfile.prod pour la production, qui est déjà correctement configuré.

3. Script de Validation d'Environnement

Fichier créé: scripts/validate-env.ts

Problème résolu: Variables d'environnement manquantes non détectées avant déploiement.

Utilisation:

# Valider les variables d'environnement
npm run validate:env

# Ou directement
ts-node scripts/validate-env.ts

Fonctionnalités:

  • Vérifie toutes les variables requises
  • Valide le format des URLs
  • Vérifie la force de NEXTAUTH_SECRET
  • Recommande les paramètres de pool DB
  • Affiche des warnings pour les variables optionnelles

Ajouté dans package.json:

"validate:env": "ts-node scripts/validate-env.ts"

🔄 Migrations à Effectuer

Priorité 1 - CRITIQUE

1. Remplacer fetch() par fetchWithTimeout()

Fichiers à modifier:

  1. lib/services/n8n-service.ts
// ❌ AVANT
const response = await fetch(this.webhookUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey },
  body: JSON.stringify(cleanData),
});

// ✅ APRÈS
import { fetchWithTimeout } from '@/lib/utils/fetch-with-timeout';

const response = await fetchWithTimeout(this.webhookUrl, {
  method: 'POST',
  timeout: 30000, // 30 secondes
  headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey },
  body: JSON.stringify(cleanData),
});
  1. app/api/missions/[missionId]/generate-plan/route.ts
// ❌ AVANT
const response = await fetch(webhookUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
  body: JSON.stringify(webhookData),
});

// ✅ APRÈS
import { fetchWithTimeout } from '@/lib/utils/fetch-with-timeout';

const response = await fetchWithTimeout(webhookUrl, {
  method: 'POST',
  timeout: 30000,
  headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
  body: JSON.stringify(webhookData),
});
  1. app/api/users/[userId]/route.ts (getLeantimeUserId)
// ❌ AVANT
const userResponse = await fetch('https://agilite.slm-lab.net/api/jsonrpc', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.LEANTIME_TOKEN || '' },
  body: JSON.stringify({ ... }),
});

// ✅ APRÈS
import { fetchJsonWithTimeout } from '@/lib/utils/fetch-with-timeout';

const userData = await fetchJsonWithTimeout('https://agilite.slm-lab.net/api/jsonrpc', {
  method: 'POST',
  timeout: 10000, // 10 secondes
  headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.LEANTIME_TOKEN || '' },
  body: JSON.stringify({ ... }),
});

2. Configurer le Pool de Connexions Prisma

Action: Modifier DATABASE_URL dans les variables d'environnement:

# ❌ AVANT
DATABASE_URL=postgresql://user:pass@host:5432/db

# ✅ APRÈS
DATABASE_URL=postgresql://user:pass@host:5432/db?connection_limit=10&pool_timeout=20&connect_timeout=10

Paramètres recommandés:

  • connection_limit=10 - Limite le nombre de connexions simultanées
  • pool_timeout=20 - Timeout pour obtenir une connexion du pool (secondes)
  • connect_timeout=10 - Timeout pour établir une connexion (secondes)

Note: Ajuster connection_limit selon la charge attendue et les limites du serveur PostgreSQL.

3. Remplacer console.log par logger

Script de migration:

# Créer scripts/migrate-console-logs.sh
#!/bin/bash

find lib/services app/api -name "*.ts" -type f | while read file; do
  # Sauvegarder d'abord
  cp "$file" "$file.bak"
  
  # Remplacer
  sed -i '' 's/console\.log(/logger.debug(/g' "$file"
  sed -i '' 's/console\.error(/logger.error(/g' "$file"
  sed -i '' 's/console\.warn(/logger.warn(/g' "$file"
  sed -i '' 's/console\.debug(/logger.debug(/g' "$file"
  
  # Vérifier que logger est importé
  if ! grep -q "import.*logger" "$file" && grep -q "logger\." "$file"; then
    # Ajouter l'import en haut du fichier
    sed -i '' '1i\
import { logger } from '\''@/lib/logger'\'';
' "$file"
  fi
done

echo "✅ Console logs migrated to logger"
echo "⚠️  Review changes and remove .bak files after verification"

Fichiers prioritaires:

  • lib/services/rocketchat-call-listener.ts (35 occurrences)
  • lib/services/refresh-manager.ts (19 occurrences)
  • lib/services/prefetch-service.ts (17 occurrences)

Priorité 2 - HAUTE

4. Activer l'Optimisation d'Images Next.js

Fichier: next.config.mjs

// ❌ AVANT
images: {
  unoptimized: true,
},

// ✅ APRÈS
images: {
  unoptimized: false,
  formats: ['image/avif', 'image/webp'],
  deviceSizes: [640, 750, 828, 1080, 1200],
  imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},

5. Implémenter Circuit Breaker

Créer lib/utils/circuit-breaker.ts (voir exemple dans PERFORMANCE_AND_PRODUCTION_ANALYSIS.md).

Services à protéger:

  • N8N webhooks
  • Leantime API
  • RocketChat API

📋 Checklist de Migration

  • Remplacer tous les fetch() par fetchWithTimeout() dans les fichiers listés
  • Configurer DATABASE_URL avec les paramètres de pool
  • Exécuter le script de migration console.log
  • Vérifier que tous les fichiers utilisent logger au lieu de console
  • Activer l'optimisation d'images dans next.config.mjs
  • Tester toutes les fonctionnalités après les changements
  • Valider l'environnement avec npm run validate:env
  • Déployer en staging et tester
  • Monitorer les performances après déploiement

🧪 Tests Recommandés

Test de Timeout

// Test que les timeouts fonctionnent
const start = Date.now();
try {
  await fetchWithTimeout('https://httpstat.us/200?sleep=5000', {
    timeout: 2000, // 2 secondes
  });
} catch (error) {
  const duration = Date.now() - start;
  console.assert(duration < 3000, 'Timeout should occur before 3 seconds');
  console.assert(error.message.includes('timeout'), 'Error should mention timeout');
}

Test de Validation d'Environnement

# Tester avec variables manquantes
unset DATABASE_URL
npm run validate:env
# Devrait échouer avec message clair

# Tester avec toutes les variables
# Devrait réussir
npm run validate:env

📚 Documentation

Voir PERFORMANCE_AND_PRODUCTION_ANALYSIS.md pour:

  • Analyse complète des problèmes
  • Recommandations détaillées
  • Métriques de succès
  • Checklist complète de mise en production

Dernière mise à jour: $(date)