Our finance dashboard showed 100% margin on every engagement. Here is what was wrong.
A double-entry ledger with no callers, demo data in production and a runway figure summed across currencies. How we rebuilt our own numbers, and a checklist for yours.
Every engagement on our finance dashboard showed a 100% margin. For a services firm that pays for software, contractors and its own time, that number is impossible. It had also been sitting there, looking authoritative, for a while.
We build operating systems for other businesses, so this was an uncomfortable find in our own back office. It's also a common one, which is why we're writing it up.
What we found
The ledger existed, but nothing wrote to it. The platform had a proper double-entry ledger in its code. When we searched for the places that called it, there were none. The chart of accounts had never been created in the database, and payments never posted.
The dashboard read revenue from somewhere else. With an empty ledger, the finance page took revenue from invoice status. An invoice marked paid counted as revenue, and costs came from a ledger that held none. Two sources of truth, one of them empty, produced a perfect margin.
Most of our billing didn't touch the platform at all. Like many small firms, we invoice a fair share of work outside our own system. Even a working invoice-driven ledger would have missed that money.
Demo data had survived into production. Seed entries created while the platform was being built were still in the live ledger. One of them matched a real client payment closely enough that it could have passed as genuine.
A quiet bug waited behind the obvious one. The cost-of-sales code referred to two different cash accounts, so once money did start posting, cash would have been split across both.
What we changed
One source of truth. The double-entry ledger is now the only place revenue, cash and burn come from. The finance page no longer reads revenue from invoice status.
Every money event posts. Issuing an invoice and each of the three places a payment can arrive now write to the ledger. Postings are calculated as the change since the last posting, so a replayed event or a partial payment can't double-count.
Money invoiced elsewhere has its own entry type. Revenue received outside the platform is recorded as a receipt. Payment and invoice entries must point to a real invoice. That rule does a second job: an entry that claims to be a payment but has no invoice behind it is exactly what leftover demo data looks like. So it can be found structurally, not by someone remembering which rows were fake. We removed the seeded entries from production and never run the seed against it.
Currencies are never added together. We earn in Kenyan shillings and US dollars. Cash, burn and runway are calculated per currency. A total across both would look precise and mean nothing, because the exchange rate on the day you add them is not the rate on the day you spend.
Burn comes from a cost register, not only from history. A trailing 90-day average sounds sensible, but in the first months of a new ledger it under-reports burn by up to three times, because most of the window is empty. Burn is now the monthly run-rate of a register of recurring costs, plus one-off costs from the last 90 days divided by three.
Runway says what it covers. Our runway figure currently covers business software only. That was a deliberate scope choice. Every report that shows it says the real runway is shorter.
Five questions for your own numbers
You don't need our stack to run this check. Ask:
1. Where does your revenue figure come from? If the answer is "paid invoices" and your costs come from somewhere else, your margin may be fiction. 2. Does anything write to the system you report from? Find the code, the integration or the person who posts each entry. If you can't, the report is decoration. 3. Is there demo, test or imported data in production? Look for records that lack what a real record always has, such as an invoice behind a payment. 4. Do you add currencies together? If yes, report them separately first and convert last, with the rate stated. 5. What does your runway leave out? Write it on the report.
A dashboard that has never surprised you probably isn't connected to anything.
Work with us
Provecta Group builds revenue and finance operations for growing businesses in Kenya and beyond, on bRRAIn, with CRM builds in HubSpot, Zoho and Odoo. If you're not sure your dashboard tells the truth, our Provecta Snapshot audit traces where each number comes from and what it misses. Book a call at pgco.world/book.
Provecta Group, a Genius Co company.