espace-paie-odentas/app/api/contrats/[id]/notes/route.ts

89 lines
No EOL
3.2 KiB
TypeScript

import { NextResponse } from "next/server";
import { createSbServer } from "@/lib/supabaseServer";
export async function GET(req: Request, ctx: { params: { id: string } }) {
const { id } = ctx.params;
try {
const sb = createSbServer();
// Try to get organization id from header if present
const activeOrg = req.headers.get("x-active-org-id") || undefined;
// Query Supabase notes table (no ordering here, we'll sort in JS)
let q = sb.from("notes").select("*");
q = q.eq("contract_id", id);
if (activeOrg) q = q.eq("organization_id", activeOrg);
// Execute query
const { data, error } = await q;
if (error) {
return NextResponse.json({ error: "supabase_error", message: error.message }, { status: 502 });
}
// Sort notes by the most relevant date:
// - For Airtable imports: use source_created_at
// - For new notes: use created_at
// Sort in descending order (newest first)
const sortedData = Array.isArray(data) ? data.sort((a, b) => {
const dateA = a.source_created_at || a.created_at;
const dateB = b.source_created_at || b.created_at;
if (!dateA && !dateB) return 0;
if (!dateA) return 1; // dateA null goes after
if (!dateB) return -1; // dateB null goes after
// Descending order: most recent first
return new Date(dateB).getTime() - new Date(dateA).getTime();
}) : [];
return NextResponse.json({ items: sortedData }, { status: 200 });
} catch (e: any) {
return NextResponse.json({ error: "internal_error", message: e?.message || String(e) }, { status: 500 });
}
}
export async function POST(req: Request, ctx: { params: { id: string } }) {
const { id } = ctx.params;
try {
const body = await req.json().catch(() => ({}));
const content: string = (body && body.content) || "";
const source: string = (body && body.source) || "Client";
if (!content || !content.trim()) {
return NextResponse.json({ error: "invalid_input", message: "content required" }, { status: 400 });
}
const sb = createSbServer();
// Récupérer l'organization_id à partir du contrat (comme dans l'API payslips)
const { data: contract, error: contractError } = await sb
.from("cddu_contracts")
.select("org_id")
.eq("id", id)
.single();
if (contractError || !contract) {
return NextResponse.json({ error: "contract_not_found", message: "Contrat non trouvé" }, { status: 404 });
}
const author = req.headers.get("x-company-name") || undefined;
const insertPayload: any = {
contract_id: id,
content: content.trim(),
source,
organization_id: contract.org_id, // Utiliser l'org_id du contrat
};
if (author) insertPayload.author = author;
const { data, error } = await sb.from("notes").insert([insertPayload]).select();
if (error) {
return NextResponse.json({ error: "supabase_error", message: error.message }, { status: 502 });
}
return NextResponse.json({ items: Array.isArray(data) ? data : [] }, { status: 201 });
} catch (e: any) {
return NextResponse.json({ error: "internal_error", message: e?.message || String(e) }, { status: 500 });
}
}