158 lines
4.7 KiB
TypeScript
158 lines
4.7 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
import { GetObjectCommand } from "@aws-sdk/client-s3";
|
|
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
|
|
import { cookies } from "next/headers";
|
|
|
|
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 BUCKET_NAME = (process.env.AWS_S3_BUCKET || "odentas-docs").trim();
|
|
|
|
// Fonction pour slugifier les noms (enlever accents, espaces, etc.)
|
|
function slugify(text: string): string {
|
|
return text
|
|
.normalize('NFD')
|
|
.replace(/[\u0300-\u036f]/g, '') // Enlever les accents
|
|
.toLowerCase()
|
|
.trim()
|
|
.replace(/[^a-z0-9]+/g, '-') // Remplacer les caractères spéciaux par des tirets
|
|
.replace(/^-+|-+$/g, ''); // Enlever les tirets en début/fin
|
|
}
|
|
|
|
// Types de documents généraux
|
|
const DOC_TYPES = {
|
|
"contrat-odentas": "Contrat Odentas",
|
|
"licence-spectacles": "Licence de spectacles",
|
|
"rib": "RIB",
|
|
"kbis-jo": "KBIS / Journal Officiel",
|
|
"delegation-signature": "Délégation de signature"
|
|
};
|
|
|
|
interface GeneralDocument {
|
|
type: string;
|
|
label: string;
|
|
available: boolean;
|
|
key?: string;
|
|
name?: string;
|
|
size?: number;
|
|
lastModified?: string;
|
|
downloadUrl?: string;
|
|
}
|
|
|
|
export async function GET(req: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(req.url);
|
|
const orgId = searchParams.get('org_id');
|
|
|
|
if (!orgId) {
|
|
return NextResponse.json({
|
|
error: "Organization ID requis"
|
|
}, { status: 400 });
|
|
}
|
|
|
|
// Vérifier l'authentification
|
|
const sb = createRouteHandlerClient({ cookies });
|
|
const { data: { user } } = await sb.auth.getUser();
|
|
|
|
if (!user) {
|
|
return NextResponse.json({
|
|
error: "Non authentifié"
|
|
}, { status: 401 });
|
|
}
|
|
|
|
// Récupérer la clé de l'organisation (structure_api)
|
|
const { data: org, error: orgError } = await sb
|
|
.from('organizations')
|
|
.select('structure_api')
|
|
.eq('id', orgId)
|
|
.single();
|
|
|
|
if (orgError || !org?.structure_api) {
|
|
return NextResponse.json({
|
|
error: "Organisation non trouvée"
|
|
}, { status: 404 });
|
|
}
|
|
|
|
const orgKey = slugify(org.structure_api);
|
|
const prefix = `documents/${orgKey}/docs-generaux/`;
|
|
|
|
// Lister les fichiers dans S3
|
|
const listCommand = new ListObjectsV2Command({
|
|
Bucket: BUCKET_NAME,
|
|
Prefix: prefix,
|
|
});
|
|
|
|
const listResponse = await s3Client.send(listCommand);
|
|
|
|
// Initialiser tous les types de documents
|
|
const documents: GeneralDocument[] = Object.entries(DOC_TYPES).map(([type, label]) => ({
|
|
type,
|
|
label,
|
|
available: false
|
|
}));
|
|
|
|
// Si des fichiers existent, les associer aux types correspondants
|
|
if (listResponse.Contents && listResponse.Contents.length > 0) {
|
|
for (const item of listResponse.Contents) {
|
|
if (!item.Key) continue;
|
|
|
|
const fileName = item.Key.split('/').pop() || '';
|
|
|
|
// Ignorer les fichiers système comme .DS_Store
|
|
if (fileName.startsWith('.') || fileName === '.DS_Store') {
|
|
continue;
|
|
}
|
|
|
|
// Déterminer le type de document basé sur le préfixe du nom de fichier
|
|
for (const [type, label] of Object.entries(DOC_TYPES)) {
|
|
if (fileName.toLowerCase().startsWith(type)) {
|
|
// Générer une URL pré-signée valide 1 heure
|
|
const getCommand = new GetObjectCommand({
|
|
Bucket: BUCKET_NAME,
|
|
Key: item.Key,
|
|
});
|
|
|
|
const signedUrl = await getSignedUrl(s3Client, getCommand, {
|
|
expiresIn: 3600 // 1 heure
|
|
});
|
|
|
|
// Trouver le document correspondant et le mettre à jour
|
|
const docIndex = documents.findIndex(d => d.type === type);
|
|
if (docIndex !== -1) {
|
|
documents[docIndex] = {
|
|
type,
|
|
label,
|
|
available: true,
|
|
key: item.Key,
|
|
name: fileName,
|
|
size: item.Size || 0,
|
|
lastModified: item.LastModified?.toISOString() || new Date().toISOString(),
|
|
downloadUrl: signedUrl
|
|
};
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({
|
|
documents,
|
|
orgKey
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Erreur récupération documents généraux S3:", error);
|
|
return NextResponse.json(
|
|
{ error: "Erreur lors de la récupération des documents" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|