feat(po-attachments): add delete route for PO additional attachments

This commit is contained in:
SJCoetz 2026-07-09 23:18:51 +02:00
parent fff095caae
commit 1477265db9

View file

@ -0,0 +1,76 @@
import { NextRequest, NextResponse } from "next/server";
import { getAdminPocketBase } from "@/lib/server/pocketbase-admin";
/**
* DELETE /api/v1/purchase-orders/[id]/attachments/[filename]
*
* Remove a single additional attachment from a PO by token. The
* `filename` segment is the PB-stored token (the same string that
* appears in `additional_attachments[]`), not the operator's
* original filename.
*
* Response:
* 200 — { ok: true, attachments: [remaining tokens] }
* 404 — { error: "Attachment not found" }
* 500 — { error: "PB admin unavailable" | <message> }
*
* Note: PB doesn't have a "delete from a multi-file field" op via
* the SDK, so we read the array, filter out the matching token, and
* write the rest back. The original PB file on disk is not deleted
* (PB doesn't expose a per-file delete from a multi-file field) —
* the token is just removed from the array, so the Send PO modal
* stops showing it. Re-uploading creates a fresh file.
*/
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export async function DELETE(
_req: NextRequest,
{ params }: { params: Promise<{ id: string; filename: string }> },
) {
const { id: poId, filename: token } = await params;
let adminPb;
try {
adminPb = await getAdminPocketBase();
} catch {
return NextResponse.json(
{ error: "PB admin unavailable" },
{ status: 500 },
);
}
try {
const po = await adminPb
.collection("purchase_orders")
.getOne<{ additional_attachments?: string[] | string }>(poId, {
fields: "id,additional_attachments",
});
const raw = po?.additional_attachments ?? [];
const arr = Array.isArray(raw) ? raw : raw ? [raw] : [];
if (!arr.includes(token)) {
return NextResponse.json(
{ error: "Attachment not found" },
{ status: 404 },
);
}
const remaining = arr.filter((t) => t !== token);
await adminPb.collection("purchase_orders").update(poId, {
additional_attachments: remaining,
});
return NextResponse.json(
{ ok: true, attachments: remaining },
{ status: 200 },
);
} catch (err) {
return NextResponse.json(
{ error: err instanceof Error ? err.message : "Delete failed" },
{ status: 500 },
);
}
}