Multimodal AI / local app

Hosted demo uses mock AI / browser-local data

Receipt AI Expense Tracker

If AI reads a receipt incorrectly, where should a person get the final say?

A local-first expense tracker that lets AI parse a receipt, but waits for a person to review and confirm before saving it.

Editable receipt extraction review before saving
Primary evidenceThe parsed result stays editable and is not saved until it is confirmed.

Multimodal AI / local app

It started with a small flow

Upload an image, extract fields, edit them, save the receipt. The edge cases appeared quickly: Buddhist Era dates, totals that do not match line items, and personal data that should not travel farther than necessary.

What I tried

  • Return a structured result from a provider or mock and run it through the same Zod validation and normalization path.
  • Normalize Buddhist Era dates and send impossible dates or invalid lines back for review.
  • Save only confirmed receipts in IndexedDB through a repository interface.

The flow

  1. 1

    Receipt image → upload validation → parse endpoint

  2. 2

    Mock / provider → Zod validation and date normalization

  3. 3

    Human review → IndexedDB → history and dashboard

Not saving automatically became the main decision

I did not want a model response to become an expense record immediately. Confidence is not a financial guarantee, so review is part of the product flow rather than a screen to hide.

Editable receipt extraction review before saving
The parsed result stays editable and is not saved until it is confirmed.

What came out of it

The synthetic fixture follows the same normalization path as provider output, supports THB and Buddhist Era dates, and routes low-confidence values back to review. That demonstrates pipeline behavior, not OCR accuracy.

Expense dashboard built from browser-local confirmed receipts
The dashboard reads only from receipts confirmed in this browser.

What's still missing

  • The public deployment uses mock AI until provider keys are configured again.
  • Data stays in one browser profile with no sync, backup, authentication, or multi-device support.
  • Images are stored as base64 in the local storage layer and can consume quota quickly.

What I'd change today

  • Build a harder receipt fixture set with tax, subtotal, and mixed Thai formats before adding more provider routing.
  • Make validation warnings easier to fix in the review screen.
  • Define export and backup before keeping real receipts for the long term.

Source and demo

The repository has the complete setup, tests, and implementation details.

See the code on GitHubTry the mock-AI demo