- Nouvelle modale UploadSignedPdfModal avec drag & drop
- API route /api/staff/amendments/[id]/upload-signed-pdf
- Upload vers S3 avec pattern avenants/{ref}_avenant_signed_{timestamp}.pdf
- Mise à jour automatique statut → 'signed' et signature_status → 'signed'
- Validation du fichier (PDF uniquement, max 10MB)
- Bouton 'Ajouter PDF signé' sur page détail avenant
152 lines
4.1 KiB
TypeScript
152 lines
4.1 KiB
TypeScript
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
|
|
import { cookies } from "next/headers";
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
|
|
const s3Client = new S3Client({
|
|
region: process.env.AWS_REGION || "eu-west-3",
|
|
credentials: {
|
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
},
|
|
});
|
|
|
|
const S3_BUCKET_NAME = process.env.S3_BUCKET_NAME || "odentas-documents";
|
|
|
|
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 },
|
|
} = await supabase.auth.getUser();
|
|
|
|
if (!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 fichier depuis le FormData
|
|
const formData = await request.formData();
|
|
const file = formData.get("file") as File;
|
|
|
|
if (!file) {
|
|
return NextResponse.json(
|
|
{ error: "Aucun fichier fourni" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Vérifier que c'est un PDF
|
|
if (file.type !== "application/pdf") {
|
|
return NextResponse.json(
|
|
{ error: "Le fichier doit être un PDF" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Vérifier la taille (max 10MB)
|
|
if (file.size > 10 * 1024 * 1024) {
|
|
return NextResponse.json(
|
|
{ error: "Le fichier ne doit pas dépasser 10 MB" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Récupérer l'avenant
|
|
const { data: avenant, error: avenantError } = await supabase
|
|
.from("avenants")
|
|
.select("numero_avenant, contract_id")
|
|
.eq("id", id)
|
|
.single();
|
|
|
|
if (avenantError || !avenant) {
|
|
return NextResponse.json(
|
|
{ error: "Avenant non trouvé" },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
// Récupérer le contrat pour avoir la référence
|
|
const { data: contract } = await supabase
|
|
.from("cddu_contracts")
|
|
.select("contract_number, reference")
|
|
.eq("id", avenant.contract_id)
|
|
.single();
|
|
|
|
const contractRef = contract?.reference || contract?.contract_number || "UNKNOWN";
|
|
|
|
// Convertir le fichier en Buffer
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const buffer = Buffer.from(arrayBuffer);
|
|
|
|
// Générer la clé S3
|
|
const timestamp = Date.now();
|
|
const s3Key = `avenants/${contractRef}_avenant_signed_${timestamp}.pdf`;
|
|
|
|
// Upload sur S3
|
|
const uploadCommand = new PutObjectCommand({
|
|
Bucket: S3_BUCKET_NAME,
|
|
Key: s3Key,
|
|
Body: buffer,
|
|
ContentType: "application/pdf",
|
|
});
|
|
|
|
await s3Client.send(uploadCommand);
|
|
|
|
const pdfUrl = `https://${S3_BUCKET_NAME}.s3.${process.env.AWS_REGION || "eu-west-3"}.amazonaws.com/${s3Key}`;
|
|
|
|
// Mettre à jour l'avenant avec la clé S3 du PDF signé
|
|
const { error: updateError } = await supabase
|
|
.from("avenants")
|
|
.update({
|
|
signed_pdf_s3_key: s3Key,
|
|
signed_pdf_url: pdfUrl,
|
|
signature_status: "signed",
|
|
statut: "signed",
|
|
})
|
|
.eq("id", id);
|
|
|
|
if (updateError) {
|
|
console.error("Erreur mise à jour avenant:", updateError);
|
|
return NextResponse.json(
|
|
{ error: "Erreur lors de la mise à jour de l'avenant" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
s3Key,
|
|
pdfUrl,
|
|
message: "PDF signé uploadé avec succès",
|
|
});
|
|
} catch (error: any) {
|
|
console.error("Erreur upload PDF signé:", error);
|
|
return NextResponse.json(
|
|
{ error: error.message || "Erreur lors de l'upload du PDF" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|