Dev spec

VapeHub Basket — Developer Implementation Notes

Companion to the design pack (vapehub-basket-IMPLEMENTATION-BRIEF.md + vapehub-product-basket-checkout-REVIEW.md, both in this folder). This records the functional decisions baked into the prototype and, for each, what the production build must supply. Where the prototype hardcodes something, it says so and points at the real source.

The basket is folded into the homepage build — vapehub-homepage-src/handover/vapehub-homepage.html, all classes/ids namespaced vhb-*, opened from the header basket icon (#vh-basket-link). /basket/ is kept as the link's real fallback href.


1. Product type — the attribute several behaviours key off

Multiple features need to know what kind of product each cart line is. The prototype fakes this with a kit:true flag on the two device lines; production needs a real type (or category) on every product, from the catalogue. Suggested values:

typeExamples
kit / deviceHayati Pro Max Plus, Aura Bar 10K, Vaporesso XROS 5
pod / refillprefilled pods, refill packs, coils
e-liquidnic salts, shortfills, 10ml
pouchnicotine pouches
accessorybatteries, chargers, cases

This single attribute drives the adaptive heading (§2), recommendation relevance (§3), and can inform multibuy grouping (§4).

2. Adaptive cross-sell heading — "how will it know?"

The question that prompted this doc: what if the basket has no kit in it?

Rule the prototype now implements — recomputed on every cart change:

``js hasKit = cart.some(line => line.type === 'kit' || line.type === 'device') heading = hasKit ? 'Complete your kit' : 'Add to your order' ``

In the prototype line.type is stood in by the kit boolean. Swap it for the real type from §1 and the rule is unchanged.

3. Recommendations (the "Complete your kit" rail) — relevance

Prototype = 3 hardcoded items. Production must select by relevance (brief §4), which needs:

Exclusions: already in cart, out of stock, discontinued. Price bias toward low-cost items (£2.89–£5.99) that help close the free-delivery gap. A hardcoded "you may also like" is explicitly not acceptable — relevance is the whole point.

4. Multibuy — confirm the model before building

Prototype applies multibuy per SKU: multibuy = {n, price}, line total = floor(qty/n)×price + (qty%n)×unitPrice. VapeHub's real deals are often mix-and-match across a group ("any 3 big-puff kits for £23", "Hayati pods 3 for £15"). Get the exact rules from the promo engine; if group-based, evaluate a deal group across cart lines, not per line. This is the single biggest logic risk (brief §3).

5. Config + real sources (currently stubbed)

ThingPrototype valueProduction source
Free-delivery threshold£30config
Delivery from£2.99config
Dispatch cutoff16:00, browser clockserver time + working-days / bank-holiday calendar (after Fri 4pm → Monday)
Loyalty earn rate10 pts/£1, 100 pts = £1real loyalty rate (confirm the scheme)
Multibuyper-SKUpromo engine (see §4)
Recommendations3 hardcodedcompatible mapping / rec service (see §3)
Paymentscards only — VISA / MC / AMEXWorldpay; express-pay slot reserved above the CTA for Apple/Google Pay when live

6. Front-end behaviour contract (built — preserve on any rebuild)

7. Still to build


Prototype reference: open the homepage build, click the header basket icon. Demo images are watermarked white-bg stand-ins with the background cut out (vapehub-homepage-src/cutout-products.py); production should use clean transparent source art.