MEGAINFRA-WEBAPP/next.config.js
DEls 05f6d551f2 feat(sites): import payment certificates into Inflows with cumulative chart
Inflows (claims) now shows only Certified invoice (VAT incl) and Retention
(ex VAT), fed by an Import certificate dialog that reads the PDF (INVOICE
TOTAL, this month's Less RETENTION, valuation number, date) for review
before saving. Adds a monthly + cumulative chart and a certificates table
linking each stored PDF.

- income_claims gains retention_amount and certificate (migration applied)
- pdftotext with an unpdf fallback for machines without poppler

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:53:54 +02:00

83 lines
3.6 KiB
JavaScript

/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: "standalone",
images: {
remotePatterns: [
// Allow image optimisation from any host. Lock this down once we
// know exactly which sources we'll pull attachments from.
{ protocol: "http", hostname: "**" },
{ protocol: "https", hostname: "**" },
],
},
// Allow any host / IP / tunneled domain so the app is reachable from
// LAN devices, reverse proxies and custom hostnames. Next 16's
// internal matcher rejects the literal "*", so we also rely on the
// `scripts/patch-next-dev-blocker.cjs` postinstall hook to neuter
// the dev-only cross-site guard. Production behaviour is unaffected
// because the patch only runs in development.
allowedDevOrigins: ["*", "192.168.50.126"],
experimental: {
serverActions: {
allowedOrigins: ["*"],
},
},
// pdfmake's server-side PdfPrinter pulls in pdfkit -> @foliojs-fork/fontkit,
// which loads font-shaping tables (data.trie etc.) from a path relative to
// its own installed location at runtime. Webpack-bundled into a Server
// Component/Route Handler chunk, that relative lookup 404s (ENOENT) because
// the .trie files never get copied alongside the bundle. Left as native
// Node `require`, the real node_modules layout resolves them correctly —
// the same reason `sharp` and `@react-pdf/renderer` ship in Next's own
// default external-packages list.
serverExternalPackages: ["pdfmake", "pdfkit", "@foliojs-fork/fontkit", "unpdf"],
// Maps moved from Sites to Surveying; keep old bookmarks working.
async redirects() {
return [
{ source: "/dashboard/sites/maps", destination: "/dashboard/surveying/maps", permanent: false },
{ source: "/dashboard/sites/:id/:map(map|map2|map3)", destination: "/dashboard/surveying/maps/:id/:map", permanent: false },
];
},
};
const withPWA = require("@ducanh2912/next-pwa").default({
// Development and production share public/sw.js. Never let a build-generated
// worker control HMR assets or rewrite the worker during local recompilation.
disable: process.env.NODE_ENV === "development",
dest: "public",
cacheOnFrontEndNav: false,
aggressiveFrontEndNavCaching: false,
reloadOnOnline: true,
register: true,
extendDefaultRuntimeCaching: true,
workboxOptions: {
cleanupOutdatedCaches: true,
clientsClaim: true,
skipWaiting: true,
runtimeCaching: [
// Account and site access can change at any time. A service worker
// must not replay another user's dashboard after sign-out.
{
urlPattern: ({ sameOrigin, url }) =>
sameOrigin && (/^\/(dashboard|clock|login|change-password)(\/|$)/.test(url.pathname) ||
url.pathname.startsWith("/api/")),
handler: "NetworkOnly",
},
// The QR confirmation must always use the server's current local-day
// decision. A cached yesterday lookup can say OUT while a POST writes IN.
{
urlPattern: ({ sameOrigin, url }) =>
sameOrigin && url.pathname === "/api/clock/employee-lookup",
handler: "NetworkOnly",
},
],
},
// The Web App Manifest lives at public/manifest.json (static file).
// next-pwa does NOT generate it — the `manifest` option was silently
// ignored in @ducanh2912/next-pwa@10.2.9. The dashboard metadata lives
// in public/manifest.json; the chat metadata lives in
// public/chat.webmanifest. Both are referenced from the per-route
// metadata blocks in src/app/layout.tsx and src/app/dashboard/chat/page.tsx.
});
module.exports = withPWA(nextConfig);