espace-paie-odentas/app/api/emails/signature-salarie/route.ts

246 lines
7.5 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { sendUniversalEmailV2, EmailDataV2 } from '@/lib/emailTemplateService';
import { ENV } from '@/lib/cleanEnv';
import { createSbServiceRole } from '@/lib/supabaseServer';
/**
* POST /api/emails/signature-salarie
*
* Route API appelée par la Lambda postDocuSealSalarie pour envoyer l'email de signature au salarié
* Utilise le système universel d'emails v2 avec logging automatique
*
* Authentification : API Key dans le header X-API-Key
*/
export async function POST(request: NextRequest) {
console.log('=== API Email Signature Salarié ===');
try {
// 1. Vérification de l'authentification via API Key
const apiKey = request.headers.get('X-API-Key');
const validApiKey = ENV.LAMBDA_API_KEY;
if (!validApiKey) {
console.error('❌ Configuration error: LAMBDA_API_KEY not configured');
return NextResponse.json(
{ error: 'Server configuration error' },
{ status: 500 }
);
}
if (!apiKey || apiKey !== validApiKey) {
console.error('❌ Unauthorized: Invalid or missing API key');
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
console.log('✅ Authentication successful');
// 2. Récupération et validation des données
const data = await request.json();
console.log('📦 Données reçues:', {
employeeEmail: data.employeeEmail,
reference: data.reference,
structure: data.structure,
firstName: data.firstName,
matricule: data.matricule
});
const {
employeeEmail,
signatureLink,
reference,
firstName: providedFirstName,
organizationName: providedOrgName,
matricule,
typecontrat,
startDate,
profession,
productionName,
organizationId,
contractId
} = data;
// Validation des champs requis
if (!employeeEmail || !signatureLink || !reference) {
console.error('❌ Champs requis manquants');
return NextResponse.json(
{
error: 'Champs manquants',
required: ['employeeEmail', 'signatureLink', 'reference']
},
{ status: 400 }
);
}
// 3. Récupération du nom du client depuis Supabase
let organizationName = 'Employeur'; // Fallback par défaut
if (!organizationId) {
console.error('❌ organization_id manquant');
return NextResponse.json(
{ error: 'organization_id est requis' },
{ status: 400 }
);
}
console.log('🔍 Récupération du nom du client depuis organizations...');
try {
const supabase = createSbServiceRole();
const { data: orgData, error: orgError } = await supabase
.from('organizations')
.select('name')
.eq('id', organizationId)
.single();
if (orgError) {
console.error('❌ Erreur lors de la récupération de l\'organisation:', orgError);
throw orgError;
}
if (orgData?.name) {
organizationName = orgData.name;
console.log('✅ Nom du client trouvé:', organizationName);
} else {
console.error('❌ Nom du client non trouvé pour org_id:', organizationId);
}
} catch (err) {
console.error('❌ Erreur lors de la récupération du nom du client:', err);
return NextResponse.json(
{ error: 'Impossible de récupérer le nom du client' },
{ status: 500 }
);
}
// 4. Récupération du prénom depuis Supabase si non fourni
let firstName = providedFirstName;
if (!firstName && (matricule || employeeEmail)) {
console.log('🔍 Récupération du prénom depuis la table salaries...');
try {
const supabase = createSbServiceRole();
// Recherche par matricule ou email
let query = supabase
.from('salaries')
.select('prenom')
.limit(1);
if (organizationId) {
query = query.eq('employer_id', organizationId);
}
// Priorité au matricule
if (matricule) {
query = query.or(`code_salarie.eq.${matricule},num_salarie.eq.${matricule}`);
} else if (employeeEmail) {
query = query.eq('adresse_mail', employeeEmail);
}
const { data: salaryData, error: salaryError } = await query;
if (!salaryError && salaryData && salaryData[0]?.prenom) {
firstName = salaryData[0].prenom;
console.log('✅ Prénom trouvé dans Supabase:', firstName);
} else {
console.warn('⚠️ Prénom non trouvé dans Supabase');
}
} catch (err) {
console.error('⚠️ Erreur lors de la récupération du prénom:', err);
}
}
// 5. Préparation des données de l'email
const emailData: EmailDataV2 = {
firstName: firstName || 'Salarié',
organizationName: organizationName,
matricule: matricule || 'N/A',
contractReference: reference,
typecontrat: typecontrat || 'CDDU',
startDate: startDate || '',
profession: profession || '',
productionName: productionName || '',
ctaUrl: signatureLink,
// Ajout des IDs pour le logging (si disponibles)
organizationId: organizationId,
contractId: contractId
};
console.log('📧 Préparation de l\'envoi de l\'email:', {
to: employeeEmail,
type: 'signature-request-salarie',
subject: `Signez votre contrat ${organizationName}`,
firstName: emailData.firstName
});
// 6. Envoi de l'email via le système universel v2
const messageId = await sendUniversalEmailV2({
type: 'signature-request-salarie',
toEmail: employeeEmail,
data: emailData,
});
console.log('✅ Email envoyé avec succès:', {
messageId,
recipient: employeeEmail,
reference
});
// 7. Mettre à jour le timestamp de dernière notification salarié et stocker le signature_link
if (contractId) {
console.log('💾 Mise à jour du contrat dans cddu_contracts...');
try {
const supabase = createSbServiceRole();
const now = new Date().toISOString();
const updateData: any = {
last_employee_notification_at: now
};
if (signatureLink) {
updateData.signature_link = signatureLink;
}
const { error: updateError } = await supabase
.from('cddu_contracts')
.update(updateData)
.eq('id', contractId);
if (updateError) {
console.error('⚠️ Erreur lors de la mise à jour:', updateError);
// Ne pas bloquer le flux, l'email est déjà envoyé
} else {
console.log('✅ Timestamp notification salarié enregistré:', now);
if (signatureLink) {
console.log('✅ signature_link stocké avec succès');
}
}
} catch (err) {
console.error('⚠️ Exception lors de la mise à jour:', err);
// Ne pas bloquer le flux
}
}
// 8. Retour du succès avec le messageId SES
return NextResponse.json({
success: true,
messageId,
recipient: employeeEmail,
reference
});
} catch (error) {
console.error('❌ Erreur lors de l\'envoi de l\'email de signature salarié:', error);
return NextResponse.json(
{
error: 'Échec de l\'envoi de l\'email',
message: error instanceof Error ? error.message : 'Unknown error'
},
{ status: 500 }
);
}
}