Move uploaded images to disk storage, fix Next 16 async params/searchParams

Homepage was rendering 71MB of HTML because every uploaded image (gallery,
products, proofs, custom requests, design previews, invoices, receipts) was
stored as base64 in Postgres and double-embedded via RSC hydration payloads.
Adds src/lib/storage.ts (sharp-based compression, disk storage under
public/uploads/) and a new /api/design-uploads endpoint for images added
inside the design tool, migrates existing rows, and drops the now-unused
base64 columns and the dead ProductImage table.

Also fixes a systemic bug from the Next.js 16 upgrade where dynamic pages
across the app still destructured params/searchParams synchronously instead
of awaiting them as Promises, which was silently breaking filters/params and
crashing /products/[slug] outright.

Updates README.md and SETUP_AND_BUILD.md to reflect Postgres + Next.js 16 and
document the new image storage architecture and backup requirements.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Andymick
2026-07-22 20:56:40 +01:00
co-authored by Claude Sonnet 5
parent e23f201d3d
commit 396347b982
72 changed files with 1399 additions and 1336 deletions
+4 -3
View File
@@ -10,10 +10,11 @@ const ERROR_MESSAGES: Record<string, string> = {
export default async function ContactPage({
searchParams,
}: {
searchParams: { sent?: string; error?: string };
searchParams: Promise<{ sent?: string; error?: string }>;
}) {
const params = await searchParams;
const customer = await getCurrentCustomer();
const error = searchParams.error ? (ERROR_MESSAGES[searchParams.error] ?? 'Something went wrong.') : null;
const error = params.error ? (ERROR_MESSAGES[params.error] ?? 'Something went wrong.') : null;
return (
<div className="mx-auto max-w-2xl px-6 py-12">
@@ -24,7 +25,7 @@ export default async function ContactPage({
back to you.
</p>
{searchParams.sent === '1' ? (
{params.sent === '1' ? (
<div className="mt-10 border border-splash-blue bg-splash-blue/5 p-6 text-sm">
Thanks we&apos;ve got your message and will be in touch soon.
</div>