Skip to content

An ERP with AI invoice capture and an audit trail that holds

Eighteen modules replacing a legacy desktop ledger, with supplier invoices captured by photograph, approvals that gate revenue, and a field-level audit log nobody can rewrite.

A regional trading & distribution groupClient engagement2026
A supplier invoice read from a photograph, its extracted lines matched to inventory items with confidence states, awaiting confirmation
The product itself, running with demonstration data.
operational modules
18
of history recovered
3 yrs
AI providers, auto-failover
2

The problem

The books lived in a proprietary desktop accounting application: one machine, one copy, no remote access, and an export path that produced nothing usable. Three years of purchase and sales history were effectively trapped inside it.

Day to day, supplier invoices arrived on paper and were re-keyed by hand into both the ledger and a stock spreadsheet. The two disagreed constantly. When a figure was wrong there was no way to establish who had changed it, or when, or what it had been before.

Anything that replaced it had to be usable on a phone in a warehouse, work for staff who should not see the accounting modules, and, critically, be trustworthy enough to run the actual books on.

What we built

01

Recovering the history before building anything

The desktop files turned out to be SQLite databases whose records were protobuf blobs. We wrote a decoder for them and recovered inventory, customers, suppliers and the full purchase and sales invoice history with line items, quantities and rates, rebuilding customer names from the audit trail where the live records had been blanked, and merging entities across books that used different identifiers. The date epoch was calibrated against a known paper invoice and verified: one document decoded to the correct date with all seven line items matching the printed amounts exactly. Loads were made idempotent, so re-running corrects rather than duplicates.

02

Capture by camera, confirmation by human

Photograph a supplier invoice and a vision model reads the line items. Nothing is written on that basis alone: the extraction is presented for review, and only the person's confirmation creates the purchase invoice and moves stock quantities, item cost prices and the supplier balance. The scanner runs across multiple API keys per provider, rotating on a schedule and advancing automatically on rate limit, quota or auth failure before falling through to a second provider. With no keys configured it says so plainly instead of failing silently.

03

Approvals that actually gate the numbers

Invoices move draft → pending review → approved → unpaid → partial → paid, and the approval step is not decorative: drafts and invoices still under review are deliberately excluded from revenue, purchases and outstanding totals on both the lists and the dashboard, because nothing is owed until an invoice is approved.

04

An audit trail that survives the application

Every write goes through a single data-access layer that stamps the acting user and appends a field-level diff to an append-only table. That table grants staff select and insert only (there is no update or delete policy), so the trail cannot be rewritten through the API even by the application itself. Deleting sets a timestamp rather than destroying the row; only an administrator can purge, and the audit entry outlives the record.

05

Permissions enforced three times over

Roles are a grid of eighteen modules against five actions, editable per role and overridable per person. Navigation hides what you cannot view, routes redirect, the write layer checks before touching the database, and a trigger discards any change a non-administrator makes to their own role or permissions. The layers above the database are the application being tidy; the trigger is what actually stops privilege escalation.

The append-only audit log, listing who changed which fields on which record
The append-only audit log, listing who changed which fields on which record

The outcome

  • Three years of trapped history recovered and reconciled against paper records, with the trading and accounting books finally in one place.

  • Invoice entry became a review task rather than a data-entry task. The model proposes, a person confirms, and the confirmation is what moves stock and balances.

  • Every change across the system is attributable, filterable and exportable, and the delete button stopped being destructive.

  • Installed as a progressive web app, it runs full-screen from the home screen and still opens cached pages when the warehouse loses signal.

Built with

  • React
  • Supabase
  • PostgreSQL
  • Row-level security
  • Claude
  • OpenAI
  • Edge Functions
  • Vercel
  • Python

Page copy drafted with AI assistance. Skofi is accountable for it. Editorial policy

Start here

Have something shaped like this?

If any part of the above resembles a problem you are living with, a short call is the fastest way to find out whether it is the same problem underneath.

Book a 15-minute callsaveez@skofi.tech

What happens on the call

  • 15 minutes, no deck
  • We map the process on the call
  • A written scope, or an honest no
Book a call