Skip to content

Sheet 01 / Work

Work

I like owning problems end-to-end: understanding the workflow, designing the system, building it, deploying it and then making sure it keeps working.

September 2026 – Present

Vanaways UK Ltd

Junior Software Engineer · Bristol, UK

I work on a greenfield in-house CRM for an FCA-regulated vehicle-finance business, replacing a legacy platform. My main focus is the customer portal, the part of the CRM that customers use themselves. I've also owned production services end to end, from data modelling and API integrations to deployment and monitoring, and built internal developer tooling.

01

Customer Portal

  • Planning and building the CRM's customer portal with one other developer. Customers open the quotes their account manager shares, accept one, and complete their finance application from their phone, with the admin fee and order signing to follow.
  • Multi-tenant from the start: each organisation's portal has its own hostname, branding and sending domain, and a customer's session only ever reaches the organisation they signed in to.
  • Finance applications prefilled from the CRM and Companies House, with document uploads and drafts saved on the server rather than the device.
  • Sensitive data sealed with per-organisation keys that can be rotated, every view of it logged, and retention rules backed by a GDPR review.
  • Account managers see their customers' portal sign-ins and visits in their CRM notifications, without duplicates.
  • Ran our shared portal branch and merged it into dev frequently, with every phase triaged through Open Code Review before merging.

02

From polling to events

  • Moved the CRM from polling to an event-driven architecture. Before, the notification badge polled every 30 seconds, conversations every 10, live calls every 5, and notification emails went out on a 15-minute sweep.
  • Traced every polling loop in the codebase first, and kept the ones that are genuinely needed, such as recovery for upstream webhooks that can go missing.
  • Changes are published from the database transaction that makes them, and Postgres LISTEN/NOTIFY wakes the API and the worker the moment they commit.
  • One authenticated Server-Sent Events stream per user says what changed; the browser refetches with its own permissions, so nothing private travels over the stream.
  • Every production email goes through a durable, lease-based queue and is sent within seconds. A send that may or may not have left during a crash is recorded as uncertain, never sent twice.
  • Rolled out behind a switch with the old path as a fallback, then retired the legacy path and moved messaging and calls onto the same stream.
Read the case study →

03

Boost — Finance API Adapter

  • Designed, built and deployed a production service connecting the CRM to external finance providers.
  • Cut the sales team's time on finance processing by more than half.
  • Implemented the compliance rules that separate regulated from unregulated agreements, based on customer type and product.
  • Worked directly with the Lloyds Lex Autolease API team to track down pricing discrepancies.
  • Built structured logging, monitoring and automated audit checks so failures surface quickly.
  • Deployed it through Coolify on a self-hosted VPS and integrated it into the wider CRM.
Read the case study →

04

Triagent — AI Code Review

  • Designed and built v1 on my own: an internal platform that runs AI code reviews from GitHub, with model choice through OpenRouter, a live dashboard over server-sent events, and an MCP interface for AI coding tools.
  • Now rebuilding it from the ground up as v2, Triagent: a self-hostable, multi-workspace app that reviews every pull request with Open Code Review.
  • A triage board shared by people and coding agents. Agents claim, fix and resolve findings over MCP, and two never pick up the same one.
  • Built around a single permission table, transactional writes with an audit log, and tests that prove one workspace can't see another's data.
  • v2 will be deployed soon.
Read the case study →
01.1

More