Skip to main content
Charlie Macnamara - Technical Writer and Developer
  • About
  • Blog
  • Portfolio
  • Contact

Four Cloudflare Workers and a Kilt Shop

Charlie MacnamaraJuly 10, 2026

Historic Edinburgh business goes 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 broken URL.

Davison Menswear hero section showing the full-page scroll layout with archival background

Spend time in Bruntsfield and you'll spot Marty: kilted, dog at heel. Generational talent. Working alone, he sews 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.

Demoing Sicamon — my Stripe CMS — was too much change. Not looking to become an overnight shop. Every tool had to feel familiar.

Design

Project splits into two main pages: public business and private orders dashboard. Tailwind enforces consistent design — utility classes, typography.

We 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 archival photo of Davison Menswear from the binder, showing the historic shopfront

Original archive binder

The site's background image composites archival photos of Davison Menswear from the 1920s-1950s

Archival photos composited into site background — binder became 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, closures.

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.

Google Reviews displayed on the site

Reviews widget on live site.

Tech Stack

Stack costs nothing. Workers scale between bookings and free tiers cover traffic.

Runs on:

  • Workers
  • D1
  • KV
  • Turnstile
  • Resend
  • Next.js
  • Tailwind
  • Google Calendar
  • GitHub Actions

Main Site

Business site's a single page: header, map, services, tartan search, reviews, and bookings.

Tartan register's nice-to-have — searchable clan directory from official hex codes.

Tartan search directory showing clan and district patterns

Searchable directory of clan and district tartans

Rest of page's more practical. Clicking "Book" triggers:

The booking form with date, time, and customer details fields

Booking form with Turnstile 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

Customer and site owner receive email alerts:

Booking confirmation screen showing the confirmed appointment
Branded booking confirmation email sent to the customer
Owner alert email notifying of a new booking

Customer sees booking confirmed.

Google Calendar showing a booked fitting appointment

Google Calendar handles booking.


Admin Dashboard

Private notepad replacement, backed by D1.

Full admin dashboard view with all management features

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.

Mobile admin page with the Add Single Order button

Add Single Order — every order starts here

Testing

Booking drop? That's a customer standing outside... five stages sit between production.

Static Analysiseslint · tsc · secretscontracts · dependency audit Worker Testsvitest + miniflareisolated runtime · no network Integration & E2EPlaywright · live APIbooking · admin · review Deploy Gatehealth probesall workers reachable Post-DeployLighthouse · every 6hauto-recovery on failure
Five QA stages: static analysis through production monitoring

Static audits catch hardcoded secrets and broken contracts before 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, Playwright. If they pass, Workers deploy in sequence: calendar, reviews, admin with D1 migrations, then main site.

Health probes verify endpoints mid‑pipeline. Deploy stops if any probe fails.

Final

Binder's back, same marquee hangs, and qualitykilts.com's live. Marty still works in his showroom — now without missed calls or double-bookings. Our family's a little bigger too.

Thanks for reading. Reach out at mail@charliemacnamara.uk.

© 2026 Charlie Macnamara. All rights reserved.

ContactPrivacy
Built on: Next.jsReactTailwindCSSAWS