Superapp / Product requirements / bluepine

Bluepine Supply — product requirements

Version 2.57 features24 requirements13 Must Open appJSONMarkdown

This product is a B2B office-supply store. A buyer signs in, browses an eight-product catalog by category and price, builds a cart with an optional promo code, checks out with a name, email and delivery address, reviews paginated order history and manages account settings. The same pricing and order rules are exposed through a REST API.

Problem. Procurement buyers need to order everyday supplies quickly and trust that every price, discount, tax amount and order number on screen is exact.

Users

Goals

Out of scope

Contents

Sign-in

Buyer login and logout.

FR-AUTH-01
Must
A valid sign-in opens the Catalog with all eight products and the buyer’s name in the header.
  • The sign-in page shows the store name as its heading and a hint about the demo account
  • After sign-in: heading "Catalog", header "Hi, Buyer", navigation Catalog / Cart (0) / Orders / Settings
  • 8 product cards, each with name, "<Category> · <SKU>", price and "Add to cart"
FR-AUTH-02
Must
A failed sign-in shows one generic message for a wrong password or a wrong-case username, and the form stays.
  • Alert reads exactly "Incorrect username or password."
  • Usernames are case-sensitive
FR-AUTH-03
Could
Sign out returns to the sign-in form and the session does not survive a reload.

Catalog

Eight products with category filter, price sort and a support link.

FR-CAT-01
Must
The Category filter shows exactly the products of the chosen category.
  • Paper (3): A4 copy paper, Sticky notes, Spiral notebook
  • Pens (2): Gel pens 10 pack, Highlighters 6 colours
  • Desk (3): Desk stapler, Monitor stand, Desk organiser
  • All: 8 products
FR-CAT-02
Must
Price sorts compare prices numerically and "high to low" is the exact reverse of "low to high".
  • Low to high: Sticky notes $4.25, Highlighters $5.75, Gel pens $6.99, A4 copy paper $9.49, Spiral notebook $12.50, Desk stapler $14.99, Desk organiser $21.50, Monitor stand $32.00
  • Desk with high to low: Monitor stand, Desk organiser, Desk stapler
FR-CAT-03
Could
The footer "Email support" link opens a message to the support address (support@ at the store own example.com domain); the API reports the same address as supportEmail.

Cart, promo code and tax

Quantities, line totals, SAVE10 promo code and 8% tax.

FR-CRT-01
Must
The navigation badge counts units (not lines) and updates immediately on every page, including the Catalog.
  • Adding "Gel pens, 10 pack" shows status "Gel pens, 10 pack added to cart." and "Cart (1)"
  • Adding it again and then "Desk stapler" shows "Cart (3)" while still on Catalog
FR-CRT-02
Must
Each line total is price × quantity, the Sub-total row sums every line, tax is 8% of the discounted sub-total rounded to the nearest cent, and Total = Sub-total − Discount + Tax.
  • 2 × A4 copy paper $9.49 + 1 × Monitor stand $32.00: lines $18.98 and $32.00, Sub-total $50.98, Tax (8%) $4.08, Total $55.06
  • Tax on a $45.88 amount is $3.67 (not rounded up)
FR-CRT-03
Must
Promo code SAVE10 takes 10% off the sub-total before tax; codes are case-insensitive.
  • Entering "save10" in the promo-code field on the $50.98 basket: Discount (SAVE10) -$5.10, Tax (8%) $3.67, Total $49.55
FR-CRT-04
Should
An unknown promo code is rejected and removes any discount already applied.
  • "SAVE50" shows an alert of the form "That <promo> code is not valid."; the Discount row disappears and Total returns to $55.06
FR-CRT-05
Should
Changing a quantity or removing a line recalculates everything; quantity has a minimum of 1.
  • A4 copy paper quantity 1: line $9.49, Sub-total $41.49, Tax $3.32, Total $44.81, "Cart (2)"
  • Quantity 0 snaps back to 1
  • Removing every line shows "Your cart is empty." and "Cart (0)"
FR-CRT-06
Could
The cart is kept for the browser tab across reloads (session storage) while the user stays signed in.

Checkout and confirmation

Validate delivery details, place the order, confirm.

FR-CHK-01
Must
Checkout requires full name, a well-formed email and a delivery address, reporting each separately, and creates no order while any is invalid.
  • Checkout shows "3 item(s) · $55.06 including tax"
  • Empty form: "Enter your full name.", "Enter a valid email address.", "Enter a delivery address."; fields are aria-invalid="true"
  • Email "ada@example" (no domain dot) leaves only "Enter a valid email address."
FR-CHK-02
Must
A valid order shows an "Order confirmed" page, empties the cart and appears first in Orders.
  • Confirmation reads "Order BP-1241 was placed: 3 item(s), $49.55." for the promo-code basket
  • Navigation reads "Cart (0)"
  • Orders first row: BP-1241 · 2026-10-02 · 3 · $49.55, "Page 1 of 3"
FR-CHK-03
Could
Direct visits to confirmation or checkout without an order or items are safe.
  • #/confirmation: "There is no recent order to show." with "Continue shopping"
  • #/checkout with an empty cart: "Your cart is empty."
  • Unknown routes show the Catalog
FR-CHK-04
Could
Orders are placed without payment; no payment details are collected.

Order history

Twelve seeded orders, newest first, five per page.

FR-ORD-01
Must
Orders list newest first, five per page, and each page shows its own rows.
  • Page 1: BP-1240 2026-09-28 1 $19.99; BP-1239 2026-09-26 2 $27.34; BP-1238 3 $34.69; BP-1237 4 $42.04; BP-1236 1 $49.39; "Page 1 of 3"; "Previous" disabled
  • Page 2: BP-1235 … BP-1231, button 2 has aria-current="page"
  • Page 3: BP-1230 and BP-1229 only; "Next" disabled

Settings

Display name and billing email.

FR-SET-01
Should
Saving settings confirms, updates the header greeting and persists across reloads.
  • Defaults: Display name "Buyer" and a seeded billing email
  • Saving "Ada" shows "Settings saved." and header "Hi, Ada"; after reload both values are kept
FR-SET-02
Should
Billing email accepts up to 40 characters, in the field and in the API.
  • A 31-character address is saved in full
  • The field keeps at most 40 characters (maxlength 40)
  • API: 40 characters returns 200; 41 returns 422 "Billing email must be at most 40 characters."

REST API

Bearer-token API mirroring the website.

FR-API-01
Should
Protected endpoints require a bearer token; login rejects bad credentials; catalog filters and sorts server-side.
  • GET /orders without a token returns 401
  • POST /auth/login with a wrong password returns 401 "Invalid credentials"; a valid login returns 200 with token and user
  • GET /products?category=Desk&sort=price-desc returns BP-302, BP-303, BP-301 and supportEmail
FR-API-02
Must
The cart-quote and promo-validation endpoints use integer cents and agree with the UI.
  • POST /cart/quote with BP-101 ×2, BP-302 ×1 and promo code "save10": items 3, sub-total 5098, discount 510, tax 367, total 4955
  • Promo code "SAVE50" returns 422 with the same "... code is not valid." message as the website
  • Validating " save10 " (padded, lower-case) returns valid true, code "SAVE10", percent 10
FR-API-03
Must
Order endpoints page the history, validate input and number new orders per session.
  • GET /orders: total 12, pages 3, pageSize 5, first BP-1240 placed 2026-09-28, items 1, total 1999; page=3 gives BP-1230, BP-1229
  • POST /orders with empty fields returns 422 with errors for name, email, address and lines ("Your cart is empty.")
  • A valid order returns 201 id BP-1241, placed 2026-10-02, items 3, total 4955
  • GET /orders/BP-1241 returns 200; /orders/BP-9999 returns 404 not_found

Non-functional requirements

NFR-01
Must
All API amounts are integer cents and displayed amounts are dollars with exactly two decimals; both always agree.
NFR-02
Should
Invalid checkout fields are exposed to assistive technology with aria-invalid and the current pagination page with aria-current="page".

Glossary and rules

SAVE10The only valid promo code; 10% off the sub-total, applied before tax.
UnitsSum of quantities across cart lines; this is what the Cart badge shows.