Skip to content
Founding beta: 7 of 50 free spots leftClaim yours

Save a cart for later (PRD)

Feature buildMediumTypeScript · FastifyDatabaseSecurityData integrity50 min

PRD-112: Save a cart for later

Owner: Rosa Alvarez (merchandising) · Reviewed by: backend lead · Target: this sprint

Goal

Shoppers often fill a cart for a project (a camping trip, a kitchen refit), then leave without buying. Let a signed-in customer put the current cart aside under a name and bring it back later, so a half-finished shopping trip is not lost and the cart is free for something else. Add this to the API; the website team builds the screens afterwards.

Requirements

All routes are under /api, need sign-in (401 otherwise), and only ever act on the caller's own saved carts. A saved cart that is not yours behaves exactly like one that does not exist (404), for staff as well.

  1. Save. POST /saved-carts with { "name": "..." } moves the whole current cart into a new saved cart and leaves the cart empty. Answer 201 with the saved cart (shape below).
    • The name is trimmed. After trimming it needs 1 to 60 characters with at least one visible character and no control characters, otherwise 400. A missing name or one that is not text is 400 too.
    • Names are unique per customer, ignoring letter case: 409 SAVED_CART_NAME_TAKEN.
    • Saving an empty cart is 409 CART_EMPTY.
    • If any of these checks refuses the request, the cart stays exactly as it was.
  2. List. GET /saved-carts returns an array of the caller's saved carts, most recently saved first (carts saved in the same millisecond: the one created later, i.e. with the higher id, comes first).
  3. Read. GET /saved-carts/:id returns one saved cart. Ids follow the same rule as other ids in this API (plain positive integers, otherwise 400).
  4. Restore. POST /saved-carts/:id/restore adds the saved lines to the current cart and answers 200 { "cart": <the current cart, as GET /cart returns it>, "skipped": [{ "product_id": 7, "reason": "unavailable" }] }.
    • Quantities add up with what is already in the cart, limited to 99 units per line and to the product's current stock.
    • A product that is archived or out of stock is not added and appears in skipped with reason unavailable.
    • The saved cart is kept after restoring (it can be restored again).

A saved cart has this shape: id, name, created_at (UTC ISO timestamp), item_count (number of lines), subtotal_cents, and items: for each line product_id, sku, name, quantity, unit_price_cents, line_total_cents and available. Prices are the products' current prices, not the prices when the cart was saved. available is false when the product is archived or has fewer units in stock than the line's quantity (as for lines in the cart).

Not in scope: deleting saved carts, a limit on how many a customer may keep, the 100-different-products cart limit during restore, sharing saved carts, expiry of old saved carts, merging prices into orders, website screens.

Acceptance

  • QA will check every rule above through the HTTP API with two customers and a staff member.
  • Existing cart, checkout and order behaviour does not change.
  • Listing saved carts and reading one stay cheap: the number of database statements must not grow with the number of saved carts or lines (no query per cart or per line).
  • Saving and restoring keep working when several requests arrive at once; two saves with the same name never both succeed.

© AICodingRound. Ticket text for practice on this site; see Terms.

How it works

  1. 1Fix the problemin a real codebase.
  2. 2Use your ownAI, or none.
  3. 3Submit, then answera few short questions.
  4. 4Get your gradeand feedback.

Guides that use this problem

All guides

More on the Cartwheel shop

View all

Related problems

View all