Four years delivering digital products in regulated environments β Tata Consultancy Services and Plusnet, on products serving 800,000+ customers β and a habit of building things end to end on my own time.
I like the unglamorous parts: what happens when the signal drops, what happens when two people press the same button, and what happens when someone pulls your app apart to see what's inside.
|
Enquiries and complaints arrive; Relay reads them, decides what they are and how urgent, extracts the commercial detail, opens the follow-up task and drafts the reply β then stops and waits for a person. Every decision lands in an audit trail. Runs on a deterministic rules engine, so the public demo costs nothing to host. The same interface drives a local model through Ollama, and the same workflows execute in n8n. |
The bit I'd point at in an interview. I ran a real model against it and caught it rewriting "revenue fell, driven by lead volume" into "driven by a decrease in conversion rate, as the conversion rate increased" β a claim that contradicted the evidence table rendered directly beneath it. So I took the model out of that path entirely, put validation on the rest, and wrote down why. Knowing when not to use the model is most of the work.
|
TurfXI: the next match screen for Sunday Legends FC, with availability, countdown and squad |
Fixtures, live match events, player ratings, subs collection. Offline-first, so it works on a pitch with no signal. React Native on iOS and Android, Postgres on Supabase. No sign-up β the demo loads a club with a full season already played. βΆ Try the demo Β· Case study |
What I found while building it. A hole that let any club member make themselves an admin of their club. I fixed it in the database policy, where a modified app can't reach it, then wrote a test that signs in as two real users and proves it's closed. That test found a second bug: it had been reading its config from the wrong directory since the day it was written, so it had never actually run.
|
Picking someone up or dropping them off at Manchester: it works back from the flight β landing, border, bags, the walk out β to the time you should leave home. Live aircraft positions refine the time from your booking; when nothing live is available, it says so instead of guessing. Costs nothing to run or to use. A scheduled GitHub Action publishes the data a browser can't fetch directly, and no credential ever reaches the page. βΆ Try it Β· Source |
What real data taught me. The first live run of the road-closures feed returned 24 disruptions near the airport β every one a routine lane closure for maintenance. Letting those widen the estimate would have put a permanent 6β12% penalty on every recommendation, and a warning that is always on is not a warning. Now only closures actually in force move the number; the rest are reported, not counted.
|
ATC Aptitude Drills: the SCALES module list, each drill showing its code, duration and what it tests |
Free, open practice for the aptitude tests used to select trainee air traffic controllers. Every drill explains the format before you start, teaches a method, and reports where you're losing marks. Nothing is uploaded β it all runs in the browser. βΆ Try it Β· Source |
Generated from my CV data on 2026εΉ΄09ζ11ζ₯ β I edit one file and this panel redraws itself.
Previously worked with
.NET Β· C# Β· VB.NET Β· Angular Β· WordPress Β· Java Β· PHP Β· MongoDB
Still readable, still useful in a code review β just not what I reach for now.
How this page maintains itself: my CV lives in one typed file in the
cv repository. That repository publishes
itself as JSON, and a scheduled workflow here fetches it and redraws the skills
panel above in both light and dark. I update one file; the CV site and this
profile follow. No badge service is involved β every image on this page is
generated in the repository and served from it.
Open to work in technical delivery, development, data or digital transformation. The quickest way to see how I build is the Relay demo above β it covers the architecture, the guardrails and the reasoning behind both.