chore(template): sync SPEC.md
This commit is contained in:
parent
e374312d7a
commit
5753b3a403
135
SPEC.md
Normal file
135
SPEC.md
Normal 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.
|
||||||
Loading…
Reference in a new issue