c990a177eb
- next.config: serverActions.bodySizeLimit + experimental.proxyClientMaxBodySize bumped from 500mb back down to 200mb. Batch ceiling (client side) is 180mb to stay comfortably under the proxy cap. - New POST /api/jobs/[jobId]/files endpoint replaces the server action for upload. Same auth/permissions/rollback semantics, but Returns JSON so the client can read the response. Server action is retained for delete only. - JobFilesPanel switched from useActionState to XMLHttpRequest.upload — xhr.upload.onprogress feeds a Progress bar (real bytes, not a fake ticker). Cancel button aborts the in-flight request. Successful upload triggers router.refresh() to repopulate the file list. Server actions can't expose upload progress (no streaming feedback in the RSC protocol yet), so any progress UX needs to go through fetch/XHR against a route handler. Trade-off accepted.
48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
import type { NextConfig } from "next";
|
|
|
|
const nextConfig: NextConfig = {
|
|
experimental: {
|
|
optimizePackageImports: ["lucide-react", "@radix-ui/react-icons"],
|
|
serverActions: {
|
|
// Job files bucket caps individual files at 30MB; allow batch uploads
|
|
// up to ~6 files of 30MB worst case.
|
|
bodySizeLimit: "200mb",
|
|
},
|
|
// Next 16 renamed `middlewareClientMaxBodySize` to `proxyClientMaxBodySize`
|
|
// (middleware.ts → proxy.ts). Default 10MB gates every body that flows
|
|
// through our auth proxy — without this override multipart uploads exceed
|
|
// the cap and the parser dies with "Unexpected end of form".
|
|
proxyClientMaxBodySize: "200mb",
|
|
},
|
|
turbopack: {},
|
|
|
|
images: {
|
|
remotePatterns: [
|
|
{ protocol: "https", hostname: "ui.shadcn.com" },
|
|
{ protocol: "https", hostname: "images.unsplash.com" },
|
|
],
|
|
formats: ["image/webp", "image/avif"],
|
|
},
|
|
|
|
async headers() {
|
|
return [
|
|
{
|
|
source: "/(.*)",
|
|
headers: [
|
|
{ key: "X-Frame-Options", value: "DENY" },
|
|
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
{ key: "Referrer-Policy", value: "origin-when-cross-origin" },
|
|
],
|
|
},
|
|
];
|
|
},
|
|
|
|
async redirects() {
|
|
return [
|
|
{ source: "/home", destination: "/dashboard", permanent: true },
|
|
];
|
|
},
|
|
};
|
|
|
|
export default nextConfig;
|