Work/Flo
A bookkeeping assistant you talk to, instead of another dashboard you have to check.
Small businesses get their bills by email and someone types them into Xero by hand. invoiceflo is my own product that does that part: it watches Gmail, pulls the details out of each invoice with Claude, files the bill in Xero and only interrupts you when it isn't sure. The interface is a chat with an assistant called flo, not a grid of forms.
- Product
- invoiceflo (my own SaaS, private alpha)
- Industry
- Small business bookkeeping
- Services
- Product design, full-stack build, AI integration, hosting
- Stack
- Next.js, Express, Postgres, Redis and BullMQ, Claude Agent SDK
- Timeline
- April to July 2026, 48 commits

The problem
Most small businesses I talk to have the same Monday job: open the inbox, find the supplier invoices, download the PDFs, type vendor, date, amount and GST into Xero, pick an account code, repeat. Bookkeeping software has had "bill capture" for years, but it still asks you to forward emails somewhere and then review every line in yet another screen.
I wanted to see whether the whole loop could run on its own and only come to you with the exceptions, in plain language, the way a sharp junior bookkeeper would. The idea came from my own books: every month I was copying the same dozen supplier invoices from Gmail into Xero, and it was exactly the kind of job I build software to get rid of.
What I built
A pnpm monorepo with a Next.js web app (installable as a PWA, with push notifications), an Express API, and a separate worker process running BullMQ queues on Redis. Gmail and Xero connect over OAuth, with Xero tokens stored AES-256-GCM encrypted. Extraction uses Claude Haiku through the Agent SDK; the chat assistant runs on Sonnet with 25 tools it can call against the user's own data.
Every user-facing string lives in one file and was written to a voice spec: lowercase, short, no grovelling, honest when Xero is down. That sounds cosmetic, but it's the product. People trust an assistant that talks like a colleague.
- 1Inbox scanning: a daily poll per Gmail account, with chained back-fill jobs for history, reading attachments, linked documents and plain email receipts.
- 2Extraction and confidence: each field gets a confidence score, GST maths is cross-checked (10%, inclusive or exclusive), and anything under 0.9 goes to the review queue instead of Xero.
- 3Filing: approved bills are created in Xero with the right account code, and foreign currency bills are converted using daily ECB rates.
- 4Memory: correct an account code once ("310 and remember it") and flo learns the vendor, with per-vendor and master switches for auto-filing.
- 5Bank checks: flo matches filed bills against Xero's bank feed, proposes payments, spots bills that were paid twice, and chases spends that have no invoice behind them.

The hard part
Accounting software doesn't forgive mistakes quietly, so most of the engineering went into not making them. Xero matches supplier bills by contact and reference number: post a bill with a number that already exists and it overwrites the original without complaint, and a voided number can never be reused. Before filing, flo looks up every bill with that number. An active twin means a real duplicate, so it refuses and says why. A voided twin means it refiles under a de-conflicted number and leaves a note on the bill.
Duplicates are subtler than matching numbers. Suppliers resend corrected invoices, recurring bills look identical month to month, and two numberless receipts both read "N/A". The detector gates on Jaro-Winkler vendor similarity first, allows three days of date drift for OCR noise, ignores placeholder invoice numbers, and treats documents from the same email as siblings. When one email carries several PDFs, auto-filing waits until the whole email has been read, so a corrected re-issue later in the thread can't lose the race to Xero.
Bank matching works the same way: weighted scores on vendor text, amount and date, exact cents for local bills and a 3% tolerance for converted ones, because the bank's rate and fees never match the reference rate exactly. When a match needs a human, flo posts a card in the chat rather than guessing.

Where it's at
invoiceflo is in private alpha on my own infrastructure, deployed with Docker Compose behind Traefik. The core loop works end to end: scan, extract, file, reconcile, chase. 9 businesses are using it, and it has filed 1,240 invoices so far. What surprised me was how quickly people stopped opening the dashboard: once flo had learned their regular suppliers, most of them only used the chat to answer its questions.
Next up is QuickBooks Online and a multi-client view for bookkeepers, both deliberately left out of V1 so the Xero path could be made trustworthy first.

More work
All case studiesOps dashboard, WooCommerce, Keap and Meta
TakeShape Adventures operations dashboard
A staff operations dashboard for an adventure travel company: every departure's manifest and check-in, trip pages edited and published back to WordPress, and the Keap and Meta automations that used to live in third-party glue, all running off one Postgres database.
SaaS, wine club management
OnCloudWine
Wine club software for wineries: members, clubs, releases, card payments and shipping in one place. It started as a WordPress plugin and grew into a multi-tenant platform with its own member portal and seven provider integrations.