Adds the full Next.js app (app/, components/, lib/, scripts/, assets/, docs/, Dockerfile, compose, configs) to version control. Security: - CIPC BizPortal customer-code logins (Login 1 + Login 3) now read CIPC_LOGIN1_CODE / CIPC_LOGIN1_PASSWORD / CIPC_LOGIN3_CODE / CIPC_LOGIN3_PASSWORD from .env.local instead of source. - BizPortal personal login in apply-bizportal route reads BIZPORTAL_ID_NO / BIZPORTAL_PASSWORD. - Added .env.example as the committed template. .gitignore excludes .env*, node_modules, .next, logs, sqlite, Playwright storage_state.json (live CIPC cookies), scratch dirs, client PDFs and debug screenshots.
50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
// app/api/documents/company/upload/route.ts
|
|
// POST — upload a document for a company
|
|
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
import { createRecordMultipart } from "@/lib/pb";
|
|
|
|
export async function POST(req: NextRequest) {
|
|
let formData: FormData;
|
|
try {
|
|
formData = await req.formData();
|
|
} catch {
|
|
return NextResponse.json({ error: "Could not parse form data" }, { status: 400 });
|
|
}
|
|
|
|
const companyId = formData.get("company_id") as string | null;
|
|
const documentTypeId = formData.get("document_type_id") as string | null;
|
|
const notes = formData.get("notes") as string | null;
|
|
const file = formData.get("file") as File | null;
|
|
const originalFilename = formData.get("original_filename") as string | null;
|
|
|
|
if (!companyId) return NextResponse.json({ error: "company_id is required" }, { status: 400 });
|
|
if (!documentTypeId) return NextResponse.json({ error: "document_type_id is required" }, { status: 400 });
|
|
if (!file) return NextResponse.json({ error: "file is required" }, { status: 400 });
|
|
|
|
const allowedTypes = ["application/pdf", "image/jpeg", "image/jpg"];
|
|
if (!allowedTypes.includes(file.type)) {
|
|
return NextResponse.json({ error: "Only PDF and JPEG files are allowed" }, { status: 400 });
|
|
}
|
|
if (file.size > 10 * 1024 * 1024) {
|
|
return NextResponse.json({ error: "File must be smaller than 10MB" }, { status: 400 });
|
|
}
|
|
|
|
try {
|
|
const record = await createRecordMultipart(
|
|
"ysterbaard_company_documents",
|
|
{
|
|
company: companyId,
|
|
document_type: documentTypeId,
|
|
notes: notes?.trim() || "",
|
|
original_filename: originalFilename || file.name,
|
|
uploaded_at: new Date().toISOString().split("T")[0],
|
|
},
|
|
[{ field: "file", file }]
|
|
);
|
|
return NextResponse.json(record, { status: 200 });
|
|
} catch (err) {
|
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
return NextResponse.json({ error: message }, { status: 502 });
|
|
}
|
|
}
|