templates2.Store.Next/README.md
w4c-templates bb75e7c742
Some checks are pending
CI / quality (push) Waiting to run
chore(template): publish Store.Next
2026-10-11 23:24:13 +03:00

56 lines
2.5 KiB
Markdown

# Online Store — Next.js (templates2)
A **ready-to-run storefront** forked from `templates2.Base.Next`: catalog, cart, checkout with the
built-in mock payment provider, customer orders and a product/order admin — plus the whole base core
(auth, roles, mock email, Docker, CI).
## Quickstart
```bash
npm ci
cp .env.example .env # SQLite + mock providers by default — no keys needed
npm run db:setup # prisma db push + seed (3 categories, 12 products, 2 orders)
npm run dev # http://localhost:3000
```
Demo accounts (seeded): `admin@example.com` (admin) and `customer@example.com` (customer) — password
`password`.
## Flow
`/shop` (search, category filters, sort, pagination) → `/shop/[slug]` (variants, stock, JSON-LD
`Product`) → `/cart` (persists in `localStorage`) → `/checkout` (**mock payment, no keys**) → order
confirmation → `/orders`. Admin: `/admin/products` (CRUD, stock, hide/show) and `/admin/orders`
(status transitions).
## What this case adds over the base
- **Data model** — `Category`, `Product` (price in minor units, stock, JSON variants), `Order`,
`OrderItem`.
- **Server-side validation** — `lib/cart.ts` recomputes every line's price from the database (never
trusts the client total), matches variants, and rejects over-stock quantities; `POST /api/checkout`
creates the order, decrements inventory and (on the mock provider) marks it paid.
- **Cart** — a client `CartProvider` backed by `localStorage`, so it survives reloads.
- **Admin** — product CRUD and order status transitions, all role-gated.
- **SEO** — `Product`/`Offer` JSON-LD per product and a sitemap that includes every active product.
- **Artwork** — a cohesive set of generated product/editorial photos in `public/art/` (hero,
collection tiles, lookbook, CTA/OG and one shot per seeded product), rendered by `<ProductImage>`,
which falls back to the emoji placeholder when a product has no image. Prompts live in
`../tools/art/store.json`; regenerate the set with
`node ../tools/generate-images.mjs ../tools/art/store.json --out /tmp/store-art` (needs
`OPENROUTER_API_KEY`), then convert to WebP into `public/art/`.
## Tests
- Unit: `tests/unit/cart.test.ts` — totals, variant deltas, empty cart, unknown product/variant,
over-stock rejection.
- E2E smoke: `tests/e2e/smoke.mjs` — catalog, filters, checkout validation and a full mock checkout.
## Quality
```bash
node templates2/qa.mjs Store.Next
```
See [`../CONTRACT.md`](../CONTRACT.md) for the Definition of Done.