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:
co-authored by
Claude Sonnet 5
parent
e23f201d3d
commit
396347b982
@@ -7,7 +7,7 @@ A complete self-hosted e-commerce platform for personalized products (apparel, d
|
||||
### Customer Experience
|
||||
- **Design Tool** — In-browser tool to customize templates with text and images
|
||||
- **Product Catalog** — Browse and filter by category, color, size, and price
|
||||
- **Shopping Cart** — Persistent cart stored in IndexedDB (handles large design files)
|
||||
- **Shopping Cart** — Persistent cart stored in IndexedDB
|
||||
- **Customer Accounts** — Optional sign-up for order history and faster checkout
|
||||
- **Dark Mode** — Full dark mode support with system preference detection
|
||||
- **Mobile Responsive** — Works seamlessly on all devices
|
||||
@@ -42,12 +42,13 @@ A complete self-hosted e-commerce platform for personalized products (apparel, d
|
||||
- **Session Expiry** — Auto-logout when browser closes
|
||||
|
||||
### Technical Stack
|
||||
- **Frontend** — Next.js 14 (App Router), React, Tailwind CSS
|
||||
- **Frontend** — Next.js 16 (App Router, Turbopack), React, Tailwind CSS
|
||||
- **Backend** — Next.js server actions, API routes
|
||||
- **Database** — SQLite with Prisma ORM
|
||||
- **Database** — PostgreSQL with Prisma ORM
|
||||
- **File storage** — Uploaded images/documents are compressed with `sharp` and saved as files on disk (`public/uploads/`), not as base64 in the database — see [Image & File Storage](#image--file-storage) below
|
||||
- **Payments** — Stripe (production-ready)
|
||||
- **Email** — SMTP (Gmail, Outlook, SendGrid, etc.)
|
||||
- **Design** — SVG-based mockups, Canvas for rendering
|
||||
- **Design** — Fabric.js/Konva canvas for the design tool, SVG-based product mockups
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -80,7 +81,7 @@ A complete self-hosted e-commerce platform for personalized products (apparel, d
|
||||
## Configuration
|
||||
|
||||
**Essential (.env):**
|
||||
- `DATABASE_URL` — SQLite path (default: `file:./dev.db`)
|
||||
- `DATABASE_URL` — PostgreSQL connection string
|
||||
- `ADMIN_USER` / `ADMIN_PASSWORD` — Admin login credentials (⚠️ change before deployment)
|
||||
- `STRIPE_SECRET_KEY` / `STRIPE_WEBHOOK_SECRET` — Stripe payment keys
|
||||
|
||||
@@ -103,11 +104,18 @@ A product can appear on both catalogs simultaneously.
|
||||
Prices stored in **GBP pence** internally. Customer-facing header currency selector (£/$/€) changes display only — no actual conversion happens until checkout is configured for it.
|
||||
|
||||
### Cart Storage
|
||||
Cart persists to **IndexedDB**, not localStorage, because design items carry large image files. IndexedDB has no 5-10MB limit like localStorage.
|
||||
Cart persists to **IndexedDB**, not localStorage, since it comfortably holds the design tool's cart items without the ~5-10MB ceiling localStorage imposes.
|
||||
|
||||
### Color Names
|
||||
Colors display as friendly names to customers (Navy, Red, Forest Green) instead of hex codes. Admin still sees hex for reference.
|
||||
|
||||
### Image & File Storage
|
||||
Every uploaded image or document (product photos, gallery photos, custom-request photos, design-approval previews, purchase invoices, expense receipts, images added inside the design tool) is saved as a real file on disk under `public/uploads/<category>/<yyyy>/<mm>/<uuid>.<ext>`, compressed and resized on the way in with `sharp`. Database columns only ever hold the resulting short URL (e.g. `/uploads/gallery/2026/07/<uuid>.jpeg`) — never a base64 data URL. PDFs (invoices/receipts) pass through untouched.
|
||||
|
||||
This matters operationally: `public/uploads/` is gitignored but lives permanently on the server's disk, so **backups must cover it alongside the database** (see [SETUP_AND_BUILD.md](./SETUP_AND_BUILD.md)). No web server config is needed to serve these files — Next.js serves everything under `public/` automatically.
|
||||
|
||||
See `src/lib/storage.ts` for the upload/compression helper and its per-category presets.
|
||||
|
||||
## Accounting Features
|
||||
|
||||
### Financial Reports
|
||||
|
||||
Reference in New Issue
Block a user