From 5753b3a4032109b3de4cfeb0518531c32ecfb635 Mon Sep 17 00:00:00 2001 From: SemianiakaVY Date: Thu, 17 Sep 2026 21:07:03 +0000 Subject: [PATCH] chore(template): sync SPEC.md --- SPEC.md | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 SPEC.md diff --git a/SPEC.md b/SPEC.md new file mode 100644 index 0000000..e559bd1 --- /dev/null +++ b/SPEC.md @@ -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 (``, ``, ``) 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 `` 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.