Solo engineer · Jun 2025 – present

Tax Tracker

A full-stack UK contractor finance product I built and use to run my own company. It tracks income, expenses and director's loans, estimates the tax I owe, and uses Gemini for receipt OCR and bank reconciliation.

  • Next.js 15 (App Router)
  • React 19
  • TypeScript
  • Drizzle ORM
  • PostgreSQL
  • Clerk
  • Expo / React Native
  • Google Gemini

The problem

I run a limited company outside IR35, and the recurring question is dull but expensive to get wrong: how much of what is sitting in the business account is actually mine, and how much do I need to put aside for tax. Spreadsheets answer that until they do not, and most off-the-shelf tools are built for accountants rather than the contractor doing their own books between client work. So I built the thing I wanted and have used it on my own finances since.

What I built

A full-stack web app with a companion Expo / React Native app sharing the same auth and data layer. The parts that earned their place:

  • Tax estimates that match my real situation. Deterministic calculation of VAT, Corporation Tax and Income Tax, plus a working-day calculator and director’s loan account (DLA) tracking with an s455 estimate. The numbers are computed in code, not by a model, so I can defend every figure.
  • Receipt OCR. Photograph a receipt and a Gemini multimodal pass returns structured expense data (supplier, date, totals, VAT, category) with field-level confidence and a graceful fallback when it cannot read something.
  • Bank reconciliation. Imported transactions are matched against recorded entries by a Gemini matcher that proposes confidence-scored accounting actions. Account numbers, sort codes, card and IBAN details are redacted before anything reaches the model, and high-confidence matches apply automatically while the rest wait for review.
  • Year-end handover. A Google Sheets export so my accountant gets clean figures without a back-and-forth.

To be clear about scope: it calculates the tax, it does not file to HMRC.

The hard part

The bank matcher had to be useful without being trusted blindly. The fix was a confidence threshold rather than a yes/no: at or above 0.85 an action applies on its own, 0.6 and up is offered as a match, below that it is a quieter suggestion. The financially consequential parts, the DLA apportionment and the s455 figure, stay fully deterministic, so the model only ever proposes bookkeeping, never computes the tax. Every run writes an audit row so I can see why a suggestion was made.

Status

In daily use for my own company. Built solo, spec-first: I direct an AI coding agent from written plans and own the architecture, review and correctness myself. It is a personal product, not a public multi-user service, and it is honestly a better record of how I work than most things I could say about it.