Skip to content

Cart optimisation

What this answers: when the user has a complete Build with components available at multiple retailers, what does the optimiser do to recommend the cheapest combination?

This page is a stub — full design lives in the upcoming RFC for #15.

Sequence

sequenceDiagram
    participant B as Browser
    participant S as Next.js server
    participant DB as Postgres
    participant Opt as Optimiser

    B->>S: GET /api/cart/aggregate?build=...
    S->>DB: SELECT Listings for each component, JOIN Retailer
    DB-->>S: rows (price, retailer, in-stock)
    S->>Opt: optimise(buildSlots, listings, shippingRules)
    Opt->>Opt: compute single-retailer subtotal per Retailer
    Opt->>Opt: compute multi-retailer optimum (combination search)
    Opt->>Opt: annotate with shipping, in-stock count, quote-only count
    Opt-->>S: trade-off matrix
    S-->>B: JSON response
    B->>B: render side-by-side options (per-retailer vs split)

What the optimiser must consider

  • Shipping cost — fixed or threshold-based per retailer (varies; needs a Reference doc when known)
  • In-stock availability — a cheaper component the retailer doesn't have isn't useful
  • Quote-only listingspriceUsd is null; can't be summed. Either exclude from total or surface as "+ ? components on quote"
  • Combinatorial explosion — 8 slots × N retailers gets large fast. With 6-8 retailers (M2 target) and 3-5 listings per slot, brute-force enumeration is fine. With more, prune aggressively.

What it does not do

  • No checkout integration. The optimiser surfaces the recommended split as URLs to follow. The user clicks through (UC-2 via deep-links) per retailer.
  • No coupon / discount codes. Out of scope.
  • No price-match guarantee logic. That's a retailer-side feature.

Open questions for the RFC

  • What's the right UX when "single retailer is $20 more but saves N deep-link clicks"? Show both options? Default to one?
  • How are quote-only listings surfaced — exclude entirely, or show "X items need a quote"?
  • Caching: optimisation results are derivable but expensive. TTL? Or recompute on each request and trust Listings change rarely?

See #15 for the implementation issue and the upcoming RFC.