124 lines
4.2 KiB
TypeScript
124 lines
4.2 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { withAuth } from '@/lib/api-guards';
|
|
import { setupLogRedaction } from '@/lib/log-redactor';
|
|
|
|
setupLogRedaction();
|
|
|
|
export const POST = withAuth(async (req, { session, prisma }) => {
|
|
try {
|
|
const body = await req.json();
|
|
const { period, simulateOnly } = body;
|
|
|
|
if (!period || !/^\d{4}-\d{2}$/.test(period)) {
|
|
return NextResponse.json(
|
|
{ error: 'El período es obligatorio y debe tener formato YYYY-MM.' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const isDev = process.env.IS_E2E_TEST === 'true' || process.env.NODE_ENV === 'development';
|
|
const signature = isDev
|
|
? (process.env.N8N_WEBHOOK_SECRET_DEV || 'qUHuPqPjA65psdtwQU7zgp/DVkvd1xXk2WP/vzbnEdc=')
|
|
: (process.env.N8N_WEBHOOK_SECRET || 'Ecjb2s33tHJppNBDJ/DxXEjHWKow8bNWmsQrk1sQKyQ=');
|
|
|
|
// Local bypass for E2E tests to prevent cloud n8n routing back to localhost
|
|
if (process.env.IS_E2E_TEST === 'true') {
|
|
console.log('E2E Test Mode: Running calculation locally via n8n endpoints...');
|
|
const localPort = process.env.PORT || '3015';
|
|
const localBase = `http://localhost:${localPort}`;
|
|
|
|
// 1. Fetch calculation data locally
|
|
const fetchRes = await fetch(`${localBase}/api/n8n/fetch-calculation-data?period=${period}`, {
|
|
headers: { 'x-n8n-signature': signature }
|
|
});
|
|
if (!fetchRes.ok) {
|
|
throw new Error(`Fetch calculation data failed: ${await fetchRes.text()}`);
|
|
}
|
|
const data = await fetchRes.json();
|
|
|
|
// 2. Process formula locally
|
|
const processRes = await fetch(`${localBase}/api/n8n/process-formula`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-n8n-signature': signature
|
|
},
|
|
body: JSON.stringify({
|
|
period,
|
|
simulateOnly,
|
|
...data
|
|
})
|
|
});
|
|
if (!processRes.ok) {
|
|
throw new Error(`Process formula failed: ${await processRes.text()}`);
|
|
}
|
|
const processData = await processRes.json();
|
|
|
|
// 3. Save settlements locally (if not simulated)
|
|
if (!simulateOnly) {
|
|
const saveRes = await fetch(`${localBase}/api/n8n/save-settlements`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-n8n-signature': signature
|
|
},
|
|
body: JSON.stringify({
|
|
period,
|
|
simulateOnly: false,
|
|
results: processData.results,
|
|
uploaderId: session.userId
|
|
})
|
|
});
|
|
if (!saveRes.ok) {
|
|
throw new Error(`Save settlements failed: ${await saveRes.text()}`);
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
code: 'SETTLEMENTS_CALCULATED',
|
|
metadata: processData.metadata,
|
|
simulated: processData.results
|
|
}, { status: 201 });
|
|
}
|
|
|
|
// Determine target n8n webhook URL for dev/prod environment
|
|
const webhookBase = process.env.N8N_API_URL || 'https://n8n.gaboggamer.online';
|
|
const webhookPath = isDev ? 'webhook-test/calculate-settlements' : 'webhook/calculate-settlements';
|
|
const webhookUrl = `${webhookBase}/${webhookPath}`;
|
|
|
|
console.log(`Triggering n8n settlement calculation webhook at ${webhookUrl}...`);
|
|
|
|
const n8nRes = await fetch(webhookUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-n8n-signature': signature
|
|
},
|
|
body: JSON.stringify({
|
|
period,
|
|
simulateOnly,
|
|
uploaderId: session.userId
|
|
})
|
|
});
|
|
|
|
if (!n8nRes.ok) {
|
|
const errText = await n8nRes.text();
|
|
console.error(`n8n webhook calculation failed with status ${n8nRes.status}:`, errText);
|
|
return NextResponse.json(
|
|
{ error: `Error del motor de cálculo externo (n8n): ${n8nRes.status}` },
|
|
{ status: 502 }
|
|
);
|
|
}
|
|
|
|
const n8nData = await n8nRes.json();
|
|
return NextResponse.json(n8nData, { status: 201 });
|
|
|
|
} catch (err: any) {
|
|
console.error('Settlement calculation trigger error:', err);
|
|
return NextResponse.json(
|
|
{ error: err.message || 'Error al calcular las liquidaciones.' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}, ['admin', 'analyst']);
|