---
title: "Invoice Automation: From a Photo to a Clean Database Row"
description: "This tool reads invoice images and writes structured data into a database, handling the messy edge cases. Here is what image-to-database really involves."
type: "build"
locale: "en"
category: "automation"
canonical: "https://agenticschool.dev/builds/invoice-automation"
dateModified: "2026-06-12"
---

# Invoice Automation: From a Photo to a Clean Database Row

- Category: automation
- Status: internal
- Stack: Gemini Vision, Node.js, Convex, TypeScript, REST API
- Updated: 2026-06-12
- Keywords: invoice automation, image to database, OCR, test data, edge cases
- Canonical URL: https://agenticschool.dev/builds/invoice-automation
- Locale: en

> Turning messy invoice images into structured data, edge cases and all.

This tool reads invoice images and writes structured data into a database, handling the messy edge cases. Here is what image-to-database really involves.

## The job: photo in, data out

The goal sounds simple: take a photo or scan of an invoice and turn it into a clean database row with the vendor, the amount, the date and the line items. In a demo it works on the first try and feels like magic. In reality, invoices are where image-to-data goes to get humbled, because no two are formatted the same.

## The edge cases are the project

The happy path took an afternoon. The edge cases took the rest of the time, and they are where all the real engineering lives. Faded scans, foreign currencies, totals that do not add up, two invoices on one page, handwriting in the margin. The model would read most of it correctly and then quietly get one digit wrong, which on an invoice is exactly the kind of mistake you cannot ship.

- I built a stack of test invoices, including deliberately ugly ones, and ran every change against all of them.
- Extracted numbers are validated against each other, so a total that does not match its line items gets flagged.
- Low-confidence fields are surfaced for a human to confirm instead of being written silently.

## Test data is the unsung hero

The single most valuable thing I built was not the extraction prompt, it was the collection of real, messy test invoices. Every time the tool failed on a new kind of document, that document went into the test set, and from then on I could never regress on it. That turned a fragile demo into something dependable. The broader lesson is that for image-to-data work, your test data is the product. The model is a commodity; the curated set of hard examples you validate against is the moat, and it is what lets you trust the output enough to put it near someone money.

## Lessons learned

- The happy path is an afternoon. The edge cases are the project. Budget your time accordingly.
- Build a growing set of real, ugly test documents. Every failure becomes a permanent regression test.
- Validate extracted data against itself. A total that does not match its line items should never pass silently.
- For image-to-data work, the curated test set is the real moat, not the prompt or the model.
