espace-paie-odentas/app/api/staff/amendments/[id]/change-status/route.ts
odentas 5b72941777 feat: Système complet de gestion des avenants avec signatures électroniques
 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'
2025-10-23 15:30:11 +02:00

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 });
}
}