Dylan Magor-Hampel

#05 · Case Study

Version status

A dashboard showing where every project sits across prod, preview, and master. Idea to deploy in a day.

Started 09 May 2026 · Done-ish 09 May 2026 · Live
Workspace opsInfrastructureFull-stackCloudflare WorkersGitHub API

Why I built this

Playing with Claude Code over the past month, my little personal tech ecosystem has escalated to three full-stack apps and two backend services, each with preview and production environments. I keep forgetting to deploy to production. Environments drift out of date relative to master. I keep causing myself confusion looking for features that aren’t there.

The other day I realised I could put together a quick dashboard showing each environment’s version and its drift from master. So I did. Over a Saturday evening, between family dinner, playing with my son, and putting him to bed, I shipped a dashboard that surfaces every project’s version state at a glance.

Version Status dashboard at /admin/versions. Five workspace projects in rows, prod / preview / master in columns. Each cell shows time-ago, a drift badge, and a commit message excerpt.
The version status dashboard at /admin/versions, all five projects loaded.

UI design (30 min elapsed · 3 iterations)

I knew I wanted a simple table-based UI, extendable to add more projects later. What I wasn’t sure about was the table’s shape. I leaned on Claude Code to visualise it, and went through three iterations.

These days, my design workflow with Claude Code is mostly Claude generating HTML mockups using my design system components and tokens. I don’t have a Figma step, or any separate design tool. It’s just Claude building mockups from my instructions, and iterating on them directly. When it comes time to implement, the mock is already real UI code, so getting a matching implementation is easy.

v1 was Claude’s first cut from the requirements I gave it. In v2 I reordered the columns to put the most important first, introduced a violet highlight for cells that need attention, and stripped commit SHAs to declutter. In v3 I dropped the dedicated Deploy column and merged it into the project column (production deploy needs a manual click; everything else is automated). Thirty minutes of iterating on the mock made it easier to reshape the design before it was implemented in code. Going straight to build would have been more difficult, and would have over-engineered the backend for data I didn’t end up needing.

Plan then build (45 min elapsed)

Implementation planning was mostly driven by Claude Code, with a bit of back-and-forth to refine the details. We landed on each app populating an environment variable with the GitHub commit hash of its live version. This gets set on each deployment, as part of the GitHub Actions pipeline. Each app exposes a /version endpoint that returns the hash. Finally, a Cloudflare Worker orchestrates the whole thing: calling each version endpoint, fetching commit history from the GitHub API, and stitching the results into the response the frontend renders.

Vertical flowchart. A browser at the top sends one request to a /api/versions handler inside the portfolio Worker. The handler talks to a caches.default sidecar with a 60-second TTL. On a cache miss the handler fans out to three destinations: the GitHub API and two grouped collections of /version endpoints, one per environment (production and preview), each containing planner-app, anecdote, identity, gateway, and portfolio. All sit outside the Worker's trust boundary.
Request flow for /api/versions. Browser, portfolio Worker, the cache sidecar, the GitHub API, and per-environment /version endpoints. The dashed Worker chamber outline marks the trust boundary.

Iterate and polish (1 hour elapsed)

After deploying, most of the data wasn’t loading. A quick investigation turned up some gaps in how the environments connected, hard to foresee in the planning stage. Easily fixed in about 20 minutes.

I also saw that the calculation for commits ahead and behind was off. I’m using a monorepo, and Claude had missed the logic to filter the GitHub API calls to each project’s path, so it was counting every commit against every project. Again, a quick fix, with a bit of care to avoid blowing through the API rate limits.

Finally, a few UI polish improvements here and there. For example, making the table scrollable on mobile.

With that, it was done. From idea to released in just 3 hours on a Saturday night, while juggling family dinner and some pre-bedtime play with my 14-month-old.