- Ajout colonne employee_docuseal_slug dans cddu_contracts - Stockage automatique du slug lors de création signature DocuSeal - Recherche directe par slug (+ rapide et fiable) - Bypass mode maintenance en localhost - Scripts de migration pour contrats existants (92 contrats migrés) - Logs détaillés dans verify-birthdate et check-status Fixes: Erreur 'Document introuvable' pour contrats anciens Performance: O(n) -> O(1) avec index sur employee_docuseal_slug
201 lines
6.8 KiB
TypeScript
201 lines
6.8 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { createSbServiceRole } from '@/lib/supabaseServer';
|
|
|
|
/**
|
|
* GET /api/signature-salarie/check-status?docuseal_id=xxx
|
|
*
|
|
* Vérifie si un contrat est déjà signé par le salarié
|
|
* Retourne les infos du contrat et l'URL de téléchargement si signé
|
|
*/
|
|
export async function GET(request: NextRequest) {
|
|
console.log('=== API Check Signature Status ===');
|
|
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const docuseal_id = searchParams.get('docuseal_id');
|
|
|
|
if (!docuseal_id) {
|
|
console.error('Paramètre manquant: docuseal_id');
|
|
return NextResponse.json(
|
|
{ error: 'Paramètre docuseal_id requis' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
console.log('Vérification du statut pour slug:', docuseal_id);
|
|
|
|
// Créer le client Supabase avec service role
|
|
const supabase = createSbServiceRole();
|
|
|
|
// NOUVELLE APPROCHE: Chercher d'abord le contrat avec le slug dans employee_docuseal_slug
|
|
console.log('Recherche du contrat par employee_docuseal_slug:', docuseal_id);
|
|
|
|
const { data: contract, error: contractError } = await supabase
|
|
.from('cddu_contracts')
|
|
.select(`
|
|
id,
|
|
contract_number,
|
|
employee_id,
|
|
org_id,
|
|
contract_pdf_s3_key,
|
|
type_de_contrat,
|
|
type_d_embauche,
|
|
multi_mois,
|
|
start_date,
|
|
end_date,
|
|
net,
|
|
gross_pay,
|
|
production_name,
|
|
structure,
|
|
profession,
|
|
role,
|
|
docuseal_submission_id,
|
|
employee_docuseal_slug
|
|
`)
|
|
.eq('employee_docuseal_slug', docuseal_id)
|
|
.maybeSingle();
|
|
|
|
if (contractError) {
|
|
console.error('Erreur lors de la recherche du contrat:', contractError);
|
|
return NextResponse.json(
|
|
{ error: 'Erreur lors de la recherche du contrat' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
if (!contract) {
|
|
console.error('Aucun contrat trouvé avec employee_docuseal_slug:', docuseal_id);
|
|
return NextResponse.json(
|
|
{ error: 'Document introuvable' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
console.log('Contrat trouvé:', {
|
|
id: contract.id,
|
|
contract_number: contract.contract_number,
|
|
docuseal_submission_id: contract.docuseal_submission_id
|
|
});
|
|
|
|
// Maintenant récupérer les infos de la submission DocuSeal si elle existe
|
|
let submission: any = null;
|
|
let employeeSubmitter: any = null;
|
|
|
|
if (contract.docuseal_submission_id) {
|
|
try {
|
|
console.log('Récupération de la submission DocuSeal:', contract.docuseal_submission_id);
|
|
const docusealResponse = await fetch(
|
|
`${process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'}/api/docuseal/submissions/${contract.docuseal_submission_id}`,
|
|
{
|
|
method: 'GET',
|
|
cache: 'no-store',
|
|
}
|
|
);
|
|
|
|
if (docusealResponse.ok) {
|
|
submission = await docusealResponse.json();
|
|
console.log('Submission récupérée');
|
|
|
|
// Trouver le submitter salarié avec ce slug
|
|
const submitters = submission.submitters || [];
|
|
employeeSubmitter = submitters.find((s: any) => s.slug === docuseal_id);
|
|
|
|
if (employeeSubmitter) {
|
|
console.log('Statut signature salarié:', {
|
|
status: employeeSubmitter.status,
|
|
completed_at: employeeSubmitter.completed_at
|
|
});
|
|
}
|
|
} else {
|
|
console.warn('Impossible de récupérer la submission DocuSeal');
|
|
}
|
|
} catch (error) {
|
|
console.warn('Erreur lors de la récupération DocuSeal (non bloquant):', error);
|
|
}
|
|
}
|
|
|
|
// 2. Récupérer les infos du salarié
|
|
const { data: employee, error: employeeError } = await supabase
|
|
.from('salaries')
|
|
.select('prenom, nom, adresse_mail, date_naissance')
|
|
.eq('id', contract.employee_id)
|
|
.maybeSingle();
|
|
|
|
if (employeeError || !employee) {
|
|
console.error('Erreur lors de la récupération du salarié:', employeeError);
|
|
}
|
|
|
|
// 3. Récupérer les infos de l'organisation
|
|
const { data: organization, error: organizationError } = await supabase
|
|
.from('organizations')
|
|
.select('name')
|
|
.eq('id', contract.org_id)
|
|
.maybeSingle();
|
|
|
|
if (organizationError || !organization) {
|
|
console.error('Erreur lors de la récupération de l organisation:', organizationError);
|
|
}
|
|
|
|
// 4. Vérifier si le salarié a déjà signé
|
|
const isSigned = employeeSubmitter && employeeSubmitter.status === 'completed';
|
|
console.log('Statut signature salarié:', {
|
|
status: employeeSubmitter?.status,
|
|
completed_at: employeeSubmitter?.completed_at,
|
|
isSigned
|
|
});
|
|
|
|
// 5. Si signé, récupérer l'URL de téléchargement du PDF
|
|
let downloadUrl = null;
|
|
if (isSigned && contract.contract_pdf_s3_key) {
|
|
console.log('Génération URL pré-signée pour:', contract.contract_pdf_s3_key);
|
|
|
|
try {
|
|
const { getS3SignedUrlIfExists } = await import('@/lib/aws-s3');
|
|
downloadUrl = await getS3SignedUrlIfExists(contract.contract_pdf_s3_key, 3600);
|
|
|
|
if (downloadUrl) {
|
|
console.log('URL pré-signée générée');
|
|
} else {
|
|
console.warn('PDF non trouvé dans S3');
|
|
}
|
|
} catch (s3Error) {
|
|
console.error('Erreur lors de la génération de l URL S3:', s3Error);
|
|
}
|
|
}
|
|
|
|
// 6. Calculer le régime (comme dans /api/contrats/[id]/route.ts)
|
|
const isMulti = contract.multi_mois === "Oui" || contract.multi_mois === true;
|
|
const td = String(contract.type_d_embauche || "").toLowerCase();
|
|
const isRG = td.includes("régime général") || td.includes("regime general") || td === "rg";
|
|
const regime = isRG ? "RG" : (isMulti ? "CDDU_MULTI" : "CDDU_MONO");
|
|
|
|
// 7. Retourner les infos
|
|
return NextResponse.json({
|
|
isSigned,
|
|
employee_birthdate: employee?.date_naissance || null,
|
|
contract: {
|
|
contract_number: contract.contract_number,
|
|
regime: regime,
|
|
start_date: contract.start_date,
|
|
end_date: contract.end_date,
|
|
gross_amount: contract.gross_pay || contract.net || 0,
|
|
employee_name: employee ? `${employee.prenom} ${employee.nom}` : null,
|
|
organization_name: organization?.name || null,
|
|
production_name: contract.production_name || contract.structure || null,
|
|
profession: contract.profession || contract.role || null,
|
|
},
|
|
signed_at: employeeSubmitter?.completed_at || null,
|
|
downloadUrl: isSigned ? downloadUrl : null,
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Erreur lors de la vérification du statut:', error);
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Erreur serveur lors de la vérification',
|
|
details: error instanceof Error ? error.message : 'Unknown error'
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|