import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from "@/app/api/auth/options"; import { logger } from '@/lib/logger'; /** * GET /api/missions/test-n8n-config * * Endpoint de test pour vérifier la configuration N8N * Permet de diagnostiquer les problèmes de connexion entre Next.js et N8N * * Authentification: Requise (session utilisateur) */ export async function GET(request: Request) { try { // Vérifier l'authentification const session = await getServerSession(authOptions); if (!session?.user) { return NextResponse.json( { error: 'Unauthorized' }, { status: 401 } ); } // Récupérer les variables d'environnement const n8nApiKey = process.env.N8N_API_KEY; const n8nWebhookUrl = process.env.N8N_WEBHOOK_URL || 'https://brain.slm-lab.net/webhook/mission-created'; const n8nRollbackWebhookUrl = process.env.N8N_ROLLBACK_WEBHOOK_URL || 'https://brain.slm-lab.net/webhook/mission-rollback'; const missionApiUrl = process.env.NEXT_PUBLIC_API_URL || 'https://api.slm-lab.net/api'; const n8nDeleteWebhookUrl = process.env.N8N_DELETE_WEBHOOK_URL; // Construire la réponse const config: { environment: { hasN8NApiKey: boolean; n8nApiKeyLength: number; n8nApiKeyPrefix: string; n8nWebhookUrl: string; n8nRollbackWebhookUrl: string; n8nDeleteWebhookUrl: string; missionApiUrl: string; }; urls: { webhookUrl: string; callbackUrl: string; rollbackUrl: string; deleteUrl: string; webhookTest?: { status?: number; statusText?: string; reachable?: boolean; note?: string; error?: string; }; }; status: { configured: boolean; missingApiKey: boolean; missingApiUrl: boolean; ready: boolean; }; recommendations: string[]; } = { // Variables d'environnement environment: { hasN8NApiKey: !!n8nApiKey, n8nApiKeyLength: n8nApiKey?.length || 0, n8nApiKeyPrefix: n8nApiKey ? `${n8nApiKey.substring(0, 4)}...` : 'none', n8nWebhookUrl, n8nRollbackWebhookUrl, n8nDeleteWebhookUrl: n8nDeleteWebhookUrl || 'not configured', missionApiUrl, }, // URLs construites urls: { webhookUrl: n8nWebhookUrl, callbackUrl: `${missionApiUrl}/api/missions/mission-created`, rollbackUrl: n8nRollbackWebhookUrl, deleteUrl: n8nDeleteWebhookUrl || 'not configured', }, // Statut de configuration status: { configured: !!n8nApiKey && !!missionApiUrl, missingApiKey: !n8nApiKey, missingApiUrl: !missionApiUrl, ready: !!n8nApiKey && !!missionApiUrl, }, // Recommandations recommendations: [], }; // Ajouter des recommandations basées sur la configuration if (!n8nApiKey) { config.recommendations.push('❌ N8N_API_KEY n\'est pas défini. Ajoutez-le à vos variables d\'environnement.'); } else { config.recommendations.push('✅ N8N_API_KEY est configuré'); } if (!missionApiUrl) { config.recommendations.push('⚠️ NEXT_PUBLIC_API_URL n\'est pas défini. Utilisation de la valeur par défaut.'); } else { config.recommendations.push('✅ NEXT_PUBLIC_API_URL est configuré'); } if (n8nApiKey && n8nApiKey.length < 10) { config.recommendations.push('⚠️ N8N_API_KEY semble trop court. Vérifiez qu\'il est correct.'); } // Tester la connectivité au webhook N8N (optionnel, peut être lent) const testWebhook = request.headers.get('x-test-webhook') === 'true'; if (testWebhook) { try { logger.debug('Testing N8N webhook connectivity', { url: n8nWebhookUrl }); const testResponse = await fetch(n8nWebhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': n8nApiKey || '', }, body: JSON.stringify({ test: true }), signal: AbortSignal.timeout(5000), // 5 secondes timeout }); config.urls.webhookTest = { status: testResponse.status, statusText: testResponse.statusText, reachable: testResponse.status !== 0, note: testResponse.status === 404 ? 'Webhook non enregistré (workflow inactif?)' : testResponse.status === 200 || testResponse.status === 400 || testResponse.status === 500 ? 'Webhook actif (peut échouer avec des données de test)' : 'Réponse inattendue', }; } catch (error) { config.urls.webhookTest = { error: error instanceof Error ? error.message : 'Unknown error', reachable: false, note: 'Impossible de joindre le webhook N8N', }; } } else { config.urls.webhookTest = { note: 'Ajoutez le header "x-test-webhook: true" pour tester la connectivité', }; } return NextResponse.json({ success: true, timestamp: new Date().toISOString(), ...config, }); } catch (error) { logger.error('Error in test-n8n-config endpoint', { error: error instanceof Error ? error.message : String(error) }); return NextResponse.json( { success: false, error: 'Failed to check N8N configuration', details: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 } ); } }