chore(template): sync SPEC.md

This commit is contained in:
SemianiakaVY 2026-09-17 21:07:03 +00:00
parent e374312d7a
commit 5753b3a403

135
SPEC.md Normal file
View file

@ -0,0 +1,135 @@
# Online Shop — product specification
This is the contract the project is built against. It is written for the agent that scaffolds
the repository, but it doubles as the human-readable brief: every requirement below is meant to
be implementable and verifiable.
Values in angle brackets (`<Store name>`, `<currency>`, `<payment provider>`) come from the
project-creation dialog and are recorded in the project record; replace them as you read.
## 1. Goal
A storefront that a real shop could launch with: browse a catalog, put items in a cart, check
out and pay, receive an order confirmation, and manage products and orders from an admin area.
It must be **runnable end-to-end on day one** (even with seeded demo data), not a set of
screens wired together later.
Non-goals (do not build unless the must-have list says otherwise): marketplace/multi-vendor,
subscriptions, warehouse/inventory integrations, tax engines, multi-language storefront.
## 2. Roles
| Role | Can do |
|------|--------|
| Visitor | Browse the catalog, search, view a product, manage a cart. |
| Customer | Everything a visitor can, plus a saved account, a checkout and an order history. |
| Admin | Manage products and categories, view and update orders, view customers. |
Authentication is required for checkout and for the admin area; anonymous browsing and cart are
allowed. Provide a seeded admin account for local development.
## 3. Information architecture (routes)
Storefront:
- `/` — home: hero, featured categories, featured products.
- `/catalog` — all products, with category filter, sort and pagination.
- `/catalog/:categorySlug` — products in one category.
- `/product/:slug` — product detail: gallery, price, stock, description, add-to-cart.
- `/cart` — cart lines, quantities, totals; continue to checkout.
- `/checkout` — shipping details, order review, payment; requires an account.
- `/checkout/success/:orderId` — confirmation with the order summary.
- `/account/orders` — order history; `/account/orders/:orderId` — one order.
- `/login`, `/register`, `/logout`.
Admin (guarded by the admin role):
- `/admin` — dashboard: recent orders, low stock, revenue for the period.
- `/admin/products` — list, create, edit, archive; image upload; stock and price.
- `/admin/categories` — list, create, edit, reorder.
- `/admin/orders` — list with status filter; `/admin/orders/:orderId` — detail + status change.
## 4. Data model
Minimum viable entities (add fields the requirements imply; keep them typed and validated):
- **Category** — id, slug, name, description, position, parentId? (optional tree).
- **Product** — id, slug, name, description, priceMinor (integer minor units), currency,
categoryId, images[], stock, status (`draft` | `active` | `archived`), createdAt.
- **Cart** / **CartItem** — cart belongs to a session or a customer; item: productId, quantity,
unitPriceMinor (snapshot at add time is NOT used for pricing — always price from the product).
- **Customer** — id, email, passwordHash, name, addresses[].
- **Order** — id, number, customerId, status (`pending` | `paid` | `fulfilled` | `cancelled`),
subtotalMinor, shippingMinor, totalMinor, currency, shippingAddress, createdAt.
- **OrderItem** — orderId, productId, name, unitPriceMinor, quantity (immutable snapshot).
- **Payment** — orderId, provider, providerRef, status, amountMinor.
Money is stored in **integer minor units** and the currency from the dialog; never use floats.
Every price is formatted with `Intl.NumberFormat`/`toLocaleString('en-US')` with the currency.
## 5. Key flows
1. **Browse → cart.** Visitor opens the catalog, filters by category, opens a product and adds
it to the cart. The cart badge updates; adding the same product again increments the quantity.
2. **Checkout.** A signed-in customer reviews the cart, enters/choose a shipping address, sees
the totals, pays with `<payment provider>` and lands on the confirmation page with the order
number. A failed payment keeps the order `pending` and shows a retry path.
3. **Order history.** The customer sees their orders newest-first and can open one to see its
immutable line items and status.
4. **Admin product lifecycle.** The admin creates a product (with an image), publishes it, sees
it in the storefront, edits the price and archives it — the archived product disappears from
the storefront but stays in past orders.
5. **Admin order handling.** The admin opens a new order, sees the items and the paid amount, and
moves it to `fulfilled`.
## 6. Functional requirements
- **Catalog:** category filter + sort (price asc/desc, newest) + pagination; empty state when a
filter matches nothing; search by name/description.
- **Product:** multiple images with a thumbnail selector; price, stock and availability;
add-to-cart disabled with a reason when out of stock.
- **Cart:** quantity edit and removal, live totals, free-shipping threshold (pick one and
document it), persisted across reloads for a signed-in customer.
- **Checkout:** server-side re-validation of prices and stock on submit; a clear error when a
product went out of stock between cart and checkout; idempotent order creation (a double
submit must not create two orders).
- **Payments:** the provider integration is behind one interface with a mock implementation used
when `None (mock)` is selected, so the flow works without keys.
- **Admin:** full CRUD for products and categories; order status transitions; no destructive
action without confirmation.
- **Seed data:** a small catalog (≥ 8 products, ≥ 3 categories, 1 admin, 1 customer, 2 orders)
so the storefront is presentable on first run.
## 7. Non-functional requirements
- **Security:** authorize every admin route and mutation server-side (never only in the UI);
hash passwords with a maintained library; keep the payment secret server-side; validate and
cap every input.
- **Accessibility:** semantic landmarks, labelled inputs, visible focus, keyboard-operable cart
and checkout, contrast at least AA.
- **Performance:** lazy-load route chunks and product images; a product list is paginated, never
unbounded.
- **Resilience:** every screen has explicit loading, empty and error states.
- **Observability:** structured logs for order creation and payment results; a health endpoint.
## 8. Acceptance criteria (definition of done)
- [ ] Install, dev server, lint, typecheck, tests and production build all pass.
- [ ] Seeded data makes the storefront presentable immediately; `.env.example` documents every secret.
- [ ] Browse → cart → checkout → payment → confirmation works end-to-end with the mock provider.
- [ ] Prices are integer minor units, formatted per currency; no floating-point money.
- [ ] Admin routes are unreachable without the admin role; order status changes are audited.
- [ ] Cart and checkout handle out-of-stock and duplicate submission correctly.
- [ ] README quickstart (install, run, test, env) is accurate; empty/loading/error states exist.
- [ ] CI runs install + lint + typecheck + tests + build.
## 9. Suggested build order
Follow this order and finish (and verify) a layer before starting the next:
1. **Scaffold** the chosen stack, install dependencies, get the dev server and the empty shell
running, and commit the skeleton.
2. **Scope**: turn the routes and the data model above into the real router and schema/migrations.
3. **Catalog + product** read paths from seeded data (this makes the app demoable).
4. **Cart + checkout + payment** (mock provider first, then the real one).
5. **Accounts + order history**.
6. **Admin** area.
7. **Quality**: tests for the flows above, CI, README, `.env.example`, accessibility pass.