All work

Doc Processor

2026 · mhmudsaed/hermes-doc-processor

Built
PythonPDF extractionSheetsTelegram

Reads invoice PDFs, checks that the numbers add up, and writes clean rows to Google Sheets. Anything that doesn't reconcile is quarantined and flagged on Telegram instead of written.

Built and verified · recorded run, offline test suite, and full source below.

The problem

Somebody retyping invoices into a spreadsheet makes one mistake in maybe fifty rows, and nobody finds it until month-end. The goal is not extraction for its own sake but extraction with checks loud enough that a bad row gets caught the day it arrives.

Pipeline architecture

Each PDF goes through text extraction, then a structured-output pass that maps the fields to a fixed schema. Rows are validated against range and arithmetic checks before anything is written. Valid rows append to a Sheet; failures are quarantined with the source page attached and a Telegram message explaining what didn't add up.

Recorded run

Recorded live in a real terminal: the offline test suite, then ./scripts/demo.sh — four clean invoices processed, and the deliberately broken fifth quarantined with the failing math shown.

pytest — 35 passed offline
pytest — 35 passed offline
Quarantine alert: totals mismatch caught before writing — accuracy check 116/116
Quarantine alert: totals mismatch caught before writing — accuracy check 116/116

Key decisions

Validation before writing, every time

A row only reaches the Sheet after its totals reconcile and its fields pass range checks. Extraction confidence is never taken on faith.

Sample documents ship with the repo

Five synthetic sample PDFs with expected outputs let anyone verify the accuracy claims with one command, instead of trusting a screenshot.

Alerts instead of dashboards

Anomalies arrive as a Telegram message the moment they happen. The dashboard is for reviewing history, not for finding out that something broke.

Guardrails

  • Originals are never modified; every output is a new file.
  • Sample documents are synthetic, so no real data ever enters the repo.
  • Every extracted row links back to its source page.

Verification

Targets cutting manual entry time on the sample documents. Verified: 100% field accuracy on the four clean samples (116/116 fields), the deliberately broken fifth quarantined by the math checks, every written row traceable to its source page.