170 lines
5.5 KiB
TypeScript
170 lines
5.5 KiB
TypeScript
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 }
|
|
);
|
|
}
|
|
}
|
|
|