Skip to content
TECH MANIAC
ALL WORK
Client engagementFOOTWEAR RETAIL · COMMERCE

VYBEZ

A women's footwear storefront built around the axis the category actually turns on — size — with Cash on Delivery as the way people pay.

EU 36–41

Size run modelled as a real variant axis

COD-first

Checkout and order lifecycle

4

Independent services: API, worker, storefront, cache

VYBEZ — Storefront home — the demo build
VYBEZ — Catalogue. Product imagery is placeholder art pending the brand's photography
VYBEZ — Product page — EU size run, quantity and Cash on Delivery. Placeholder imagery
VYBEZ — Cash-on-Delivery checkout

STOREFRONT HOME — THE DEMO BUILD

THE PROBLEM

Footwear is a size business. A customer does not want the shoe, they want the shoe in a 38, and a store that treats size as an afterthought discovers the problem when the first order arrives for a pair that does not exist. Retrofitting a proper variant axis into a catalogue that already has orders against it is a data migration, and it is the kind nobody wants to run twice.

The second constraint is how the country pays. Cash on Delivery is not a fallback here, it is the default, and platforms built elsewhere treat it as an edge case — confirming orders when money settles rather than when the customer places them, and assuming an email address exists to send that confirmation to.

The brand needed a store it could see and use before committing to photography and a launch date. That meant a real, running system rather than a design file: a working checkout, a real admin, real size variants — reviewable, but honest about being a demo.

WHAT WE BUILT

STOREFRONT

  • Category and collection pages across heels, sandals, sneakers and flats
  • Product pages with the full EU 36–41 size run, a quantity stepper and a zoomable gallery
  • Cash-on-Delivery checkout with inside- and outside-Dhaka delivery
  • Customer accounts and order history
  • Buy Now, routing straight to checkout at the address step

OPERATIONS

  • Admin dashboard for catalogue, orders, stock and shipping
  • A worker process, separate from the API, for jobs and email
  • Product media on object storage behind the brand's own CDN subdomain
  • Bangladesh store configuration: BDT, tax-inclusive pricing, COD as a payment provider

SHAPE OF IT

Four independent services on one box: the commerce API, a worker, the storefront, and the cache each run as their own unit against a shared PostgreSQL database. Everything binds to loopback and is reached through nginx, so nothing but ports 80 and 443 is exposed. The storefront never talks to the database — it goes through the commerce API only, which is what allows the two to be deployed, restarted and debugged independently.

ON MISSAPI ONLYCONSUMESSHOPPERphoneCDNedge cacheNGINXloopback only past hereSTOREFRONTNext.jsCOMMERCE APIMedusaWORKERjobs · emailPOSTGREScatalogue · ordersVALKEYqueue · workflow stateOBJECT STOREproduct media
FOUR SERVICES, ONE DATABASE — THE STOREFRONT NEVER TOUCHES IT DIRECTLY
ONE WAYBOTH WAYSPERIODIC
MedusaNext.jsPostgreSQLValkeyCloudflare R2

DECISIONS THAT MATTERED

The parts that were not obvious.

01

Size is a variant axis from the first migration

Shoes are a size business, so the variant axis was modelled properly before a single product existed rather than added once the catalogue was populated. Eight styles carry forty-eight variants between them — a full EU 36–41 run each. The alternative, encoding size in the product title or a custom field, works right up until you need stock per size, and then it is a migration against live orders.

02

The cache is not a cache, so it never evicts

This instance holds workflow state, the event bus and the job queue — not disposable copies of things that exist elsewhere. It therefore runs with eviction disabled and append-only persistence on, and that combination was verified by writing a key, restarting the unit, and reading it back. With snapshot-only persistence a redeploy silently drops queued order work. An eviction policy would do the same thing under memory pressure, quietly, at exactly the wrong moment.

03

VAT is switched on at zero rather than switched off

The region is configured tax-inclusive with a zero rate, not tax-exclusive. The distinction is invisible today and decisive later: prices entered in the admin are treated as VAT-inclusive, so when VAT is eventually enabled the tax is carved out of the existing price. Had the region been left tax-exclusive, turning VAT on would have raised every price in the catalogue by fifteen per cent overnight.

04

Delivery zones follow couriers, not administrative boundaries

Inside Dhaka and outside Dhaka are two shipping options within a single service zone, rather than two geographic zones. Geographic zones key off country, province and city, and Bangladesh's administrative divisions do not match how couriers price a parcel — "inside Dhaka" is a metro area, not a division. The customer picks the option and the courier confirms at pickup, which is how the transaction already works offline.

05

The admin and the storefront are never allowed to share a dependency tree

The admin dashboard runs on React 18 and the storefront on React 19, in separate package trees with separate lockfiles. They are deliberately not hoisted or deduplicated into a workspace. It is the sort of tidying that looks like an obvious improvement and fails at runtime rather than at build, which is the worst place to find it.

06

A confirmation screen may not claim an email was sent

The starter's order confirmation told customers their details had been emailed. No mail system existed yet, so the sentence was simply false, and it is the exact failure a sibling project shipped for weeks — a contact form that reported success and dropped the message. The wording now states what actually happened: the order is confirmed, to be paid in cash on delivery. It changes back when mail is real, and not before.

Shoes are a size business. Model that axis on day one, or migrate it later against live orders.

WHERE IT LANDED

  • A complete purchase path — size selection, cart, address, Cash on Delivery, order placed — driven end to end in a real browser rather than asserted from code.
  • Four services running independently, so the storefront can be rebuilt and restarted without touching the commerce API or the queue.
  • Product media served from the brand's own CDN subdomain with a year-long cache lifetime.
  • A reviewable demo the brand can walk through before committing to photography or a launch date.
  • Not launched, and not trading. The catalogue is demo data and the product imagery is placeholder art pending the brand's own photography.