Four Cloudflare Workers and a Kilt Shop
How a historic Edinburgh business went programmatic.
June 2026, my sister got married — congrats, Floyd — so I needed a kilt. Davison Menswear & Kilt Hire happened to be close. Shop was easy to spot: hand-painted marquee, logo, Est. 1927, and a previously broken URL.

Kilt year-round — dog, pub, behind the counter. Open the door and Marty knows your name, last fitting, clan. He works alone, sewing from memory, in a showroom unchanged since his father's day.
His methods, while proven, showed age: calendar bookings misplaced, missed calls, staying late to rewrite orders. He was keen on upgrading; old site was down for years.
Requirements
Unrealistic to expect a kilt maker to learn new tools after decades on paper.
I demoed Sicamon — a Stripe CMS. Understandably, this was too much change. Not looking to become an overnight online shop. Every tool feels familiar.
Stack costs nothing. Workers scale between bookings and free tiers cover traffic. Each worker deploys independently, minimising risk.
Runs on:
- Workers
- D1
- KV
- Turnstile
- Resend
- Next.js
- Tailwind
- Google Calendar
- GitHub Actions
Design
Project splits into two main pages: public business and a private orders dashboard. Tailwind enforces a consistent design system — utility classes, no magic numbers. Fluid typography.
I wanted heritage design notes. Marty handed me a binder of original marketing adverts from 1920/1950: hand-drawn illustrations, commissioned artwork (took ages to scan).

Original archive binder
Using a translucent white overlay, adverts bleed through as you scroll.

Archival photos composited into the site background — binder became the brand.
Workers
Admin Dashboard Worker — Order management backed by D1. Status tracking, CSV exports, automated emails.
Calendar Worker — Dedicated worker with its own credentials. Talks to Google Calendar for slot management — availability checks, event creation, and closure detection.
Frontend Worker — The shop window. Serves every page — hero, map, services, tartan search widget, reviews, and booking button. Static build, globally distributed.
Reviews Worker — Pulls Google Reviews on a schedule into KV. Fresh content, zero effort.

Reviews widget on the live site.
Main Site
Business site is a single page: header, map, services, tartan search, reviews, and bookings.
Tartan register is a nice-to-have novelty; searchable directory of clan patterns rendered from official tartan hex codes.

Searchable directory of clan and district tartans — a fun bonus for visitors
Rest of page is more practical. Clicking "Book" triggers:

The booking form — Turnstile bot protection runs invisibly on submit
Booking Pipeline
- Bot detection — Turnstile, invisible
- Input validation — malformed data rejected
- Closure check — reads
[Closed]calendar events - Slot availability — no double-booking
- Event creation — writes to Google Calendar
- Cancel link — signed JWT in the event
- Notifications — async emails to both customer and site owner, never blocks



First, the customer sees the booking confirmed — the appointment locks in and emails go out.

Google Calendar handles the booking slots — already in place before this project.
Admin Dashboard
Private notepad replacement page. Independent Cloudflare Worker backed by D1.

Full admin dashboard
Four statuses: In Progress, Ready, Delivered, Cancelled. Every transition logged immutably — who changed it, when, and whether the email went out.
Emails fire on status changes via Resend. Receipt includes bank details — stored as Worker secrets, never in the codebase. On creation, the customer gets payment instructions. When ready, a collection email fires.
CSV export: current tax year, last year, or custom range. Clean totals.
Quick Add for reconciling past orders.
Add Single Order — measurement references and a notify toggle, with an option for group orders.

Add Single Order — every order starts here
Testing
This runs a business. If a booking drops, that's a customer standing outside.
Five stages sit between production. Static audits catch hardcoded secrets and broken contracts before a test even runs. Worker tests (Vitest + Miniflare) mock every external dependency.
Integration and E2E tests prove real integrations work (Google Calendar, Resend, Turnstile) and drive full booking flow and admin lifecycle.
Pre-deploy checks probe all workers before deployments. If something's degraded, the deploy stops. Once live, post-deploy monitoring probes every six hours, runs a worker self-check, and Lighthouse scores every deploy.
CI/CD
Every push to main runs lint, TypeScript,
audit rules, worker tests, and
Playwright
. If they pass, Workers deploy in sequence: calendar first, then reviews, admin
dashboard with D1 migrations, then the main site.
Health probes verify endpoints mid‑pipeline. Site uses a safe rollout: build, upload, promote.
Final
Binder's back, same marquee hangs, and qualitykilts.com is live. Marty still works in his showroom — now without missed calls or double-bookings.
Thanks for reading. Reach out at mail@charliemacnamara.uk.
