122 lines
No EOL
4 KiB
TypeScript
122 lines
No EOL
4 KiB
TypeScript
// app/api/documents/route.ts
|
|
export const dynamic = "force-dynamic";
|
|
import { NextResponse } from "next/server";
|
|
import { cookies } from "next/headers";
|
|
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
|
|
|
|
function json(status: number, body: any) {
|
|
return NextResponse.json(body, { status });
|
|
}
|
|
|
|
export async function GET(req: Request) {
|
|
try {
|
|
const c = cookies();
|
|
const sb = createRouteHandlerClient({ cookies });
|
|
|
|
// 1) Récupérer la catégorie depuis les query params
|
|
const { searchParams } = new URL(req.url);
|
|
const category = searchParams.get("category");
|
|
|
|
if (!category) {
|
|
return json(400, { error: "missing_category_parameter" });
|
|
}
|
|
|
|
console.log('📄 Documents API - Category:', category);
|
|
|
|
// 2) Déterminer l'organisation active
|
|
let orgId = c.get("active_org_id")?.value || "";
|
|
|
|
console.log('📄 Documents API - Org ID from cookie:', orgId);
|
|
console.log('📄 Documents API - All cookies:', {
|
|
active_org_id: c.get("active_org_id")?.value,
|
|
active_org_name: c.get("active_org_name")?.value,
|
|
active_org_key: c.get("active_org_key")?.value,
|
|
});
|
|
|
|
// 3) Si pas d'orgId dans les cookies, vérifier si c'est un client authentifié
|
|
if (!orgId) {
|
|
const { data: { user }, error: userError } = await sb.auth.getUser();
|
|
|
|
console.log('📄 Documents API - User:', user?.id, 'Error:', userError);
|
|
|
|
if (!user) {
|
|
return json(401, { error: "unauthorized", details: "No user found" });
|
|
}
|
|
|
|
// Vérifier si c'est un staff
|
|
const { data: staffUser } = await sb
|
|
.from("staff_users")
|
|
.select("is_staff")
|
|
.eq("user_id", user.id)
|
|
.maybeSingle();
|
|
|
|
console.log('📄 Documents API - Is staff?', staffUser?.is_staff);
|
|
|
|
// Si c'est un staff sans org sélectionnée, retourner une erreur explicite
|
|
if (staffUser?.is_staff) {
|
|
return json(400, {
|
|
error: "no_organization_selected",
|
|
details: "Staff user must select an organization first"
|
|
});
|
|
}
|
|
|
|
// Récupérer l'organisation du client via organization_members
|
|
const { data: member, error: memberError } = await sb
|
|
.from("organization_members")
|
|
.select("org_id")
|
|
.eq("user_id", user.id)
|
|
.eq("revoked", false)
|
|
.maybeSingle();
|
|
|
|
console.log('📄 Documents API - Member:', member, 'Error:', memberError);
|
|
|
|
if (member?.org_id) {
|
|
orgId = member.org_id;
|
|
console.log('📄 Documents API - Org ID from member:', orgId);
|
|
}
|
|
}
|
|
|
|
if (!orgId) {
|
|
return json(400, { error: "no_organization_found" });
|
|
}
|
|
|
|
// 4) Récupérer les documents depuis Supabase avec RLS
|
|
console.log('📄 Documents API - Fetching from Supabase with org_id:', orgId, 'category:', category);
|
|
|
|
const { data: documents, error } = await sb
|
|
.from("documents")
|
|
.select("*")
|
|
.eq("org_id", orgId)
|
|
.eq("category", category)
|
|
.order("date_added", { ascending: false });
|
|
|
|
if (error) {
|
|
console.error('📄 Documents API - Supabase Error:', error);
|
|
return json(500, { error: "supabase_error", details: error.message });
|
|
}
|
|
|
|
console.log('📄 Documents API - Found documents:', documents?.length || 0);
|
|
|
|
// 5) Transformer les documents au format attendé par le frontend
|
|
const formattedDocuments = (documents || []).map(doc => ({
|
|
id: doc.id,
|
|
title: doc.filename || doc.type_label || 'Document',
|
|
url: doc.storage_path, // L'URL S3 présignée sera générée côté client si nécessaire
|
|
updatedAt: doc.date_added,
|
|
sizeBytes: doc.size_bytes || 0,
|
|
period_label: doc.period_label,
|
|
meta: {
|
|
category: doc.category,
|
|
type_label: doc.type_label,
|
|
}
|
|
}));
|
|
|
|
console.log('📄 Documents API - Returning formatted documents:', formattedDocuments.length);
|
|
|
|
return json(200, formattedDocuments);
|
|
|
|
} catch (err: any) {
|
|
console.error('📄 Documents API - Unexpected error:', err);
|
|
return json(500, { error: "server_error", message: err.message });
|
|
}
|
|
} |