✨ Nouvelles fonctionnalités - Page de gestion des avenants (/staff/avenants) - Page de détail d'un avenant (/staff/avenants/[id]) - Création d'avenants (objet, durée, rémunération) - Génération automatique de PDF d'avenant - Signature électronique via DocuSeal (employeur puis salarié) - Changement manuel du statut d'un avenant - Suppression d'avenants 🔧 Routes API - POST /api/staff/amendments/create - Créer un avenant - POST /api/staff/amendments/generate-pdf - Générer le PDF - POST /api/staff/amendments/[id]/send-signature - Envoyer en signature - POST /api/staff/amendments/[id]/change-status - Changer le statut - POST /api/webhooks/docuseal-amendment - Webhook après signature employeur - GET /api/signatures-electroniques/avenants - Liste des avenants en signature 📧 Système email universel v2 - Migration vers le système universel v2 pour les emails d'avenants - Template 'signature-request-employee-amendment' pour salariés - Insertion automatique dans DynamoDB pour la Lambda - Mise à jour automatique du statut dans Supabase 🗄️ Base de données - Table 'avenants' avec tous les champs (objet, durée, rémunération) - Colonnes de notification (last_employer_notification_at, last_employee_notification_at) - Liaison avec cddu_contracts 🎨 Composants - AvenantDetailPageClient - Détail complet d'un avenant - ChangeStatusModal - Changement de statut manuel - SendSignatureModal - Envoi en signature - DeleteAvenantModal - Suppression avec confirmation - AvenantSuccessModal - Confirmation de création 📚 Documentation - AVENANT_EMAIL_SYSTEM_MIGRATION.md - Guide complet de migration 🐛 Corrections - Fix parsing défensif dans Lambda AWS - Fix récupération des données depuis DynamoDB - Fix statut MFA !== 'verified' au lieu de === 'unverified'
90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
|
|
import { cookies } from "next/headers";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export async function POST(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ id: string }> }
|
|
) {
|
|
try {
|
|
const { id } = await params;
|
|
const supabase = createRouteHandlerClient({ cookies });
|
|
|
|
// Vérifier l'authentification
|
|
const { data: { user }, error: authError } = await supabase.auth.getUser();
|
|
if (authError || !user) {
|
|
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
|
|
}
|
|
|
|
// Vérifier que l'utilisateur est staff
|
|
const { data: staffUser } = await supabase
|
|
.from("staff_users")
|
|
.select("is_staff")
|
|
.eq("user_id", user.id)
|
|
.maybeSingle();
|
|
|
|
if (!staffUser?.is_staff) {
|
|
return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
|
|
}
|
|
|
|
// Récupérer le nouveau statut
|
|
const body = await request.json();
|
|
const { status: newStatus } = body;
|
|
|
|
// Valider le statut
|
|
const validStatuses = ["draft", "pending", "signed", "cancelled"];
|
|
if (!newStatus || !validStatuses.includes(newStatus)) {
|
|
return NextResponse.json({
|
|
error: "Statut invalide. Statuts acceptés : draft, pending, signed, cancelled"
|
|
}, { status: 400 });
|
|
}
|
|
|
|
// Vérifier que l'avenant existe
|
|
const { data: avenant, error: fetchError } = await supabase
|
|
.from("avenants")
|
|
.select("id, statut, signature_status")
|
|
.eq("id", id)
|
|
.single();
|
|
|
|
if (fetchError || !avenant) {
|
|
return NextResponse.json({ error: "Avenant non trouvé" }, { status: 404 });
|
|
}
|
|
|
|
// Mettre à jour le statut de l'avenant
|
|
const updateData: any = {
|
|
statut: newStatus,
|
|
updated_at: new Date().toISOString(),
|
|
};
|
|
|
|
// Si on repasse en brouillon, réinitialiser aussi le signature_status
|
|
if (newStatus === "draft") {
|
|
updateData.signature_status = "not_sent";
|
|
}
|
|
|
|
const { error: updateError } = await supabase
|
|
.from("avenants")
|
|
.update(updateData)
|
|
.eq("id", id);
|
|
|
|
if (updateError) {
|
|
console.error("Erreur mise à jour statut:", updateError);
|
|
return NextResponse.json({
|
|
error: "Erreur lors de la mise à jour du statut"
|
|
}, { status: 500 });
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: `Statut modifié avec succès : ${newStatus}`,
|
|
newStatus,
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Erreur changement statut:", error);
|
|
return NextResponse.json({
|
|
error: "Erreur serveur"
|
|
}, { status: 500 });
|
|
}
|
|
}
|