Intelligence

Artifacts

Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.

Repository
globals.csslayout.tsxnot-found.tsxpage.tsx
.gitignoreDockerfilenext-env.d.tsnext.config.mjspackage-lock.jsonpackage.jsonpostcss.config.mjsREADME.mdtailwind.config.tstsconfig.jsontsconfig.tsbuildinfo
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
repositories/aaf-holdings/hq01/app/api/files/upload/route.ts
1.7 KB
import { NextResponse } from "next/server";
import { saveToFolder, FileOpError } from "@/lib/files/manager";
import { MAX_UPLOAD_BYTES } from "@/lib/files/config";

/**
 * Upload a document into a specific managed folder (file-manager "Upload here").
 *
 *   POST /api/files/upload   (multipart/form-data)
 *     - dir:  target folder (relative path within a managed root)
 *     - file: the uploaded document
 */

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

export async function POST(request: Request) {
  let form: FormData;
  try {
    form = await request.formData();
  } catch {
    return NextResponse.json(
      { error: "Expected multipart/form-data." },
      { status: 400 },
    );
  }

  const dir = form.get("dir");
  const file = form.get("file");

  if (typeof dir !== "string" || !dir) {
    return NextResponse.json(
      { error: "A target folder is required." },
      { status: 400 },
    );
  }
  if (!(file instanceof File)) {
    return NextResponse.json({ error: "A file is required." }, { status: 400 });
  }
  if (file.size > MAX_UPLOAD_BYTES) {
    return NextResponse.json(
      { error: "File exceeds the 25MB limit." },
      { status: 413 },
    );
  }

  try {
    const data = Buffer.from(await file.arrayBuffer());
    const result = saveToFolder(dir, file.name, file.size, data);
    return NextResponse.json({ ok: true, result }, { status: 201 });
  } catch (err) {
    if (err instanceof FileOpError) {
      return NextResponse.json({ error: err.message }, { status: err.status });
    }
    const message = err instanceof Error ? err.message : "Upload failed.";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}

root · /srv/aaf