1. Work
  2. Glowlight Med Spa
  3. The booking flow
Live since September 2026

Custom Front-Ends

When the vendor’s widget won’t do.

Interfaces built on top of someone else’s API, shaped deliberately to behave like whatever the people using them already know.

Role
Sole engineer
Stack
Boulevard GraphQL API, PHP, vanilla JS
Period
May to September 2026
Status
Live since September 2026

01The rebuild

The booking rebuild

The clinic booked through a hosted widget it could not style, could not instrument, and could not extend. Bookings that came through it arrived in analytics with no source attached.

Front desk staff had used that flow for years.

A better flow that behaved differently would cost more in retraining and mistakes than it earned in elegance. Same order, same wording, same number of taps.

So the build ran in two passes.

  1. Write a booking flow from scratch against the API
  2. Walk the vendor’s own hosted widget, screen by screen, and rebuild the new flow to match it exactly
  • Full service catalog with categories, a multi-treatment cart, and add-ons
  • Provider selection with live per-provider availability
  • A month-grid calendar that paints without spinners, using speculative prefetch on the dates a user is likely to open next
  • A native date picker on mobile instead of a rebuilt one
  • Card checkout through Boulevard’s card vault, so card numbers never reach our server
  • SMS sign-in, with an account picker for clients who have more than one record
  • A waitlist, location-aware phone numbers and promo codes, added after launch
  • Tested end to end with a real appointment before launch

02The audit

Then I audited it

A build this size, going onto a live medical calendar, does not get to be trusted because its author feels good about it. It got a nine-area correctness audit, each area cross-checked against the vendor’s published SDK rather than against my own assumptions.

  • ScopeNine areas, each cross-checked against the vendor’s published SDK
  • Root causeTwo separate symptoms, one architectural mistake: the code sent changes to the booking system without reading the cart back, so the screens after service selection showed what the user intended rather than what the system actually held
  • Also caughtA gap in the safeguard against test bookings
  • OutcomeBoth fixed before cutover, along with a pass on the mobile layout

03Sign-in

Duplicate client records

Boulevard’s phone verification attaches the cart to an arbitrary record when one phone number belongs to more than one client, which is common in a clinic’s records.

Not this

Merge the duplicates in Boulevard, changing patient records to work around a sign-in bug.

Instead

Rebuild sign-in on Boulevard’s passwordless multi-client auth, with an account picker.

The working version mints signed, client-scoped access tokens on the server. The client ID only ever comes from Boulevard’s response to an SMS-verified phone number.

04Security

Security and tests

Cart binding

Each cart is bound to the browser that created it, through a cookie set by an uncached request because the host’s page cache strips cookies from page renders.

Pen test

Before launch the flow went through white-box penetration testing, and the launch blockers it found were closed before cutover.

Tests

The real booking modules run against WordPress stubs with no network, covering the launch blockers and promo codes. There is no CI; the deploy scripts lint every file on the server.

05Status board

The client status board

A different problem, same shape: build the interface the situation actually needs instead of accepting the one you are handed.

Working across seven surfaces for several owners generates a specific overhead, which is the same status question asked separately by different people and answered slightly differently each time. Written updates go stale the day after they are sent.

  • Password-gated, hand-rolled, static, no framework, because a status board should not have a build step that can fail on the day someone needs to read it
  • A Gantt-style timeline generated entirely from ISO dates, so nothing is positioned by hand
  • A shipped log and per-project detail pages, all from the same source
  • A presence system with working-hours logic, so the owners can see when I am working
  • One editable data file drives every page, which is the only reason it stays current

The failure mode of a status document is that maintaining it costs more than the confusion it prevents, so it quietly stops being maintained. Collapsing every page down to one file was the whole design goal.