Digital agency · billing platform
The agency billed every month out of a Google Sheet. Twelve people editing one spreadsheet, no audit trail beyond version history, and a cycle that took four to five days across finance and a dozen project managers. What bothered me most wasn't the time — it was that revenue had no real subledger. The sheet was the system of record, and anyone could edit it silently.
I'm not a software engineer. I'm building it anyway — pairing with Claude nights and weekends, treating my finance knowledge as the spec and the AI as the hands on the keyboard.
Status: still being built. It isn't finished and it hasn't replaced anything. Each month it runs alongside the live billing process and gets scored on whether it can reproduce what actually got invoiced — which is how I find out what's still wrong with it.
175 statements of work reconciled
One month's run, scored line by line against the invoices that actually went out. This is the test it has to keep passing, month after month, before it earns the right to replace anything.
What it does
Imports a monthly ad spend report covering roughly thirty client campaigns, matches each spend line to a client, and computes the management fee from that client's actual contract terms — flat percentages, tiered brackets, minimums, maximums, annual caps, and parent/child accounts that share an aggregate fee. Umbrella accounts needing their spend split across child campaigns are caught at intake and can't reach invoicing until someone resolves the split.
Ingests worklogs, maps every hour to a department and a statement of work, and gives each project manager one review screen: what was logged, what was billed, and the decision the month turns on. Retainers carry hour banks that roll month to month with over- and under-burn tracked and every rolling balance auditable back through its history. Projects get a three-outcome decision — value bill, billable overage, or write-off — with the maths already done for the PM.
Department-level revenue recognition moves are captured on each monthly review and roll up into a balanced journal entry. Every correction, override, sign-off and decision is logged with who, when, and why. That's the subledger the spreadsheet never was.
The app
client names pseudonymised, amounts masked
Will it work
Encouraging, not conclusive. Two months of scored runs isn't proof, and the variances that turned up are the point of running it this way — each one is either a bug to fix or something the old process was getting wrong.
The result I'd point at is the dropped spend row. That month the app wasn't just reproducing the spreadsheet — it found something the spreadsheet had quietly got wrong.
How it's being built
Every month-end close is a test suite. When the app and the spreadsheet disagree, we chase the variance until one of them turns out to be wrong. Several times now it's been the spreadsheet — which is the whole argument for building this.
Where it goes from here
The work continues each month. The direction we're heading is to fold this functionality into the agency's existing operations platform, so there's one system rather than two — with this app serving as the working spec and the reference implementation for that build.
I'll take that trade. What I'm after is a billing cycle with a real audit trail behind it instead of a spreadsheet's version history — and that survives the move.
Built with Claude Code. Reviewed, reconciled, and argued with by a finance person who now can't stop shipping software. One of several things built for the agency.