src/app/api/documents/route.ts
Linked repository file from this build.
import { NextResponse } from "next/server";
import { z } from "zod";
import { apiRoute } from "@/lib/api-route";
import { getActor } from "@/lib/auth/server";
import { AccessError, can } from "@/lib/auth/scope";
import {
DocumentError,
documentKeySchema,
documentStorage,
putLocalDocument,
uploadOwner,
uploadRequestSchema,
} from "@/lib/documents/server-storage";
export const runtime = "nodejs";
export const POST = apiRoute(
"Unable to save PDF. Check the file and try again.",
async (request) => {
const actor = await getActor(request);
if (!can(actor, "uploadDocuments")) throw new AccessError("This role cannot upload documents.");
const storage = documentStorage();
if (request.headers.get("content-type")?.startsWith("application/json")) {
const input: unknown = await request.json();
if (storage.mode === "local") return NextResponse.json({ mode: "local" });
const owner = uploadOwner(actor.program, actor.staffId);
const completion = z.object({ uploadId: documentKeySchema }).safeParse(input);
if (completion.success)
return NextResponse.json({ key: await storage.complete(completion.data.uploadId, owner) });
const parsed = uploadRequestSchema.safeParse(input);
if (!parsed.success) throw new DocumentError("Select a PDF file, 10 MB or smaller.");
return NextResponse.json({ mode: "neon", ...(await storage.prepare(parsed.data, owner)) });
}
if (storage.mode !== "local") throw new DocumentError("Start a direct document upload first.");
const file = (await request.formData()).get("file");
if (!(file instanceof File)) throw new DocumentError("Select a PDF file.");
return NextResponse.json({
key: await putLocalDocument(file, uploadOwner(actor.program, actor.staffId)),
});
},
);