Skip to content

Product engineer · Greater Manchester

I build software people rely on while they’re busy doing something else.

I’m Wes. I drive buses for the Bee Network, and I design, build and run three products on Laravel — a platform for small businesses, a football booking app and the app my depot’s drivers use — from the database to the button, then support them in production.

products live in production
3
automated tests across them
2,300+
business types one platform serves
5
person designing, building and running them
1

Selected work

Three products, all live, all mine to support.

Rather than screenshots, here are the decisions that shaped each one: what went wrong or could have, what I chose, and what it cost.

01

SiteSoup

A multi-tenant platform that runs small businesses’ websites, orders and payments.

I build a polished site for a café, barber, holiday let or shop, hand it over, and the owner runs their business from it: online ordering, bookings, a stock-aware shop, Stripe payouts, a phone app for staff. One codebase, five business types, every query scoped to its tenant.

Used by Small UK business owners and their customers

  • Laravel
  • Livewire
  • Alpine
  • Filament
  • MySQL
  • Redis/Horizon
  • Stripe Connect
  • Gemini
  • MCP
tests
1,160+
business modes
5
MCP tools for AI assistants
20+
Visit sitesoup.co.uk

Problem

I gave Claude and Codex an MCP server so they could read and edit client sites. A chat that read a page ten minutes ago would happily save over whatever the owner changed since.

Decision

Every page edit must send back the updated_at it read. If the page moved on, the write is refused and the assistant has to read again. Omitting a field leaves it alone, so fixing a title can’t wipe a description.

Trade-off

Some deliberately missing tools: an assistant can see whether a page is indexed but can’t noindex it. Hiding a client from Google by accident isn’t a mistake worth putting one sentence away.

02

Fancy A Game?

Casual football you can book like a cinema ticket.

Find a game near you, pay in one tap, get a place or an automatic waitlist spot, then play in teams balanced from real ratings. Players earn a FIFA-style card from match results, not from what they claim on their profile.

Used by Local five- and seven-a-side players, and the hosts who run games

  • Laravel
  • Livewire
  • Filament
  • MySQL
  • Stripe Checkout
  • PWA
tests
760+
booking decisions
Row-locked
book and pay
1 tap
Visit fancyagame.co.uk

Problem

Two players tapping “Book” on the final place at the same moment is the normal case for a popular game, not an edge case.

Decision

Booking decisions run in a database transaction with row locks. A place is held briefly while the player pays; expired holds release automatically and promote the next person on the waitlist.

Trade-off

Holds make capacity look full for a few minutes while someone is paying. A scheduled job cleans them up, and players see a clear “held” state rather than a surprise.

03

Driver Hub

A phone app bus drivers open before every shift.

I drive buses for the Bee Network out of Stagecoach’s Oldham depot, and built Driver Hub because I wanted it myself. It pulls each driver’s duties from the depot’s rostering system, shows the next shift and a live countdown, route notes, published diversions and private pay estimates. It’s built for someone glancing at a phone in a cab, not for a desk.

Used by Me and fellow drivers at Oldham depot

  • Laravel
  • Livewire
  • Filament
  • Redis/Horizon
  • Gemini
  • PWA
  • TfGM open data
tests
380+
rota sync
Hourly
pay estimates
Owner-only

Problem

Rosters live in a web system with rate limits and odd data: the last bus is “24:00”, late duties end before they start, and a flaky day must not delete a driver’s history.

Decision

A dedicated Horizon queue, incremental detail fetching, 403 and 429 kept distinct so a driver sees “slow down” versus “reconnect”, and reconciliation that keeps known-good rows until a complete replacement arrives.

Trade-off

Keeping old rows means occasionally showing yesterday’s truth for a little longer. For pay and hours, stale beats missing.

Try it

Small working pieces of each product.

Rebuilt in React for this page, with the same rules the real apps follow. They run entirely in your browser.
Business type
Brand colour

Preview width

the-good-spud.co.uk
The Good SpudBasket · 0

Order ahead, skip the queue.

Collection or table service, paid by card.

  • Loaded jacket, chilli & cheese£7.50
  • Tuna crunch jacket£6.95
  • Flat white£3.20
  • Total£0.00

A sketch of SiteSoup’s five business modes. The real thing handles payments, stock, bookings and staff apps.

How I work

Product first, then the code that makes it dependable.

01

Evidence over hype

Every decision above started with a real failure or a real user complaint, and ended with a test that reproduces it.

02

Own the whole feature

I take things from “this is annoying” to released: database, API, interface, deploy, and the message a user sees when it goes wrong.

03

AI-assisted, human-owned

I build with coding agents every day — and review every diff, because I’m the one supporting it. I also build AI features, and care most about how their output is shown and checked.

04

Built for the person using it

A driver in a cab, a café owner mid-service, a player on a touchline. Clear states, plain language, nothing that needs a manual.

What I work with

Front end

  • React + TypeScript (this site)
  • Livewire + Alpine
  • Tailwind CSS
  • Accessible, responsive UI
  • PWAs

Back end

  • Laravel
  • MySQL
  • Redis + Horizon queues
  • REST APIs + webhooks
  • Multi-tenancy

Product & AI

  • LLM features (Gemini, Claude)
  • MCP servers
  • Stripe + Stripe Connect
  • Testing (PHPUnit, Vitest)
  • Laravel Forge deploys

Contact

Building something people depend on? I’d like to help.

Based in Greater Manchester, happy to be in the office and on calls.

© 2026 Wes Singleton

Built with React and TypeScript · pre-rendered, then hydrated · served by SiteSoup, my own platform.