Files
v2.app.gaertan.art/src/actions/commissions/submitCommissionRequest.ts

99 lines
2.5 KiB
TypeScript

"use server";
import { z } from "zod";
/**
* Server action
* Forwards a multipart/form-data request (payload + files[])
* from the public app to the admin app's public commissions endpoint.
*
* Server-only env required:
* ADMIN_URL=https://admin.domain.com
*/
const submitPayloadSchema = z.object({
typeId: z.string().optional().nullable(),
optionId: z.string().optional().nullable(),
extraIds: z.array(z.string()).default([]),
customerName: z.string().min(1),
customerEmail: z.string().email(),
customerSocials: z.string().optional().nullable(),
message: z.string().min(1),
});
export type SubmitCommissionPayload = z.infer<typeof submitPayloadSchema>;
export async function submitCommissionRequest(input: {
payload: SubmitCommissionPayload;
files: File[];
}) {
const adminUrl = process.env.ADMIN_URL;
if (!adminUrl) {
throw new Error("ADMIN_URL is not set on the server");
}
const payload = submitPayloadSchema.parse(input.payload);
const files = input.files ?? [];
// Optional safety limits
const MAX_FILES = 10;
const MAX_BYTES_EACH = 10 * 1024 * 1024; // 10MB
if (files.length > MAX_FILES) {
throw new Error("Too many files");
}
for (const f of files) {
if (f.size > MAX_BYTES_EACH) {
throw new Error(`File too large: ${f.name}`);
}
}
const fd = new FormData();
fd.set("payload", JSON.stringify(payload));
for (const file of files) {
fd.append("files", file, file.name);
}
const res = await fetch(
`${adminUrl.replace(/\/$/, "")}/api/v1/commissions`,
{
method: "POST",
body: fd,
cache: "no-store",
}
);
if (!res.ok) {
const raw = await res.text().catch(() => "");
const statusLine = `${res.status} ${res.statusText || ""}`.trim();
// Show something useful even if raw is empty
let message = `Admin API error: ${statusLine}`;
if (raw) {
try {
const parsed = JSON.parse(raw);
message =
parsed?.error
? `Admin API error: ${statusLine}${parsed.error}`
: parsed?.message
? `Admin API error: ${statusLine}${parsed.message}`
: `Admin API error: ${statusLine}${raw}`;
} catch {
message = `Admin API error: ${statusLine}${raw}`;
}
}
// Log full body server-side for debugging (safe; this is server-only)
console.error("[submitCommissionRequest] upstream error", { statusLine, raw });
throw new Error(message);
}
// Expected response: { id: string; createdAt: string }
return (await res.json()) as { id: string; createdAt: string };
}