TONY LAROCCO

← ProjectsAI track

Receipt AI

React Native / Expo · TypeScript · FastAPI · Postgres · Clerk · Render · Sentry

Full-stack receipt product: mobile capture → cloud extraction → review → categorized spend insights.

Context

Most “receipt AI” demos stop at a pretty OCR screenshot. Real spend only becomes trustworthy when capture, processing, human review, and categorization hold up together—on a phone, under bad lighting, with money that must not drift by a cent, and with auth and ops that survive more than a weekend hack.

Receipts are hostile inputs: crumpled paper, glare, multi-vendor layouts, partial totals, tips, tax lines, and the human habit of photographing “good enough.” Automation that pretends every capture is perfect ships silent wrong money. The product problem is not “can a model read text?”—it is “can a person trust the spend signal after the system has done its best?”

I set out to ship a product path, not a notebook: something a person can use to turn messy paper and photo receipts into reviewable, categorized spend signals.

What I built

I own the full stack for this product: an Expo / React Native mobile client, a FastAPI backend, Postgres, Clerk authentication, and production hosting and observability on Render with Sentry (plus secrets management and private networking in the ops layer).

What that ownership actually means day to day:

Mobile is the capture surface and the place trust is felt—upload flow, review UI, and scrolling performance once real volume exists.

API + database own lifecycle: a receipt is not a single row of “done,” it moves through states so half-processed work does not become fake truth.

Auth is part of the product, not a checkbox—who can see which receipts has to be correct before insights mean anything.

Ops is early on purpose: deploys, scheduled work, error tracking, secrets, and a private path into the environment so production failures are visible instead of mythical.

The public story stays simple. The engineering is the seams: typed contracts between app and API, lifecycle that does not strand work, money treated as something you cannot casually float, and mobile performance measured when it hurts.

How it works

At product altitude the loop is four stages, with an explicit trust gate:

Capture — the mobile app is where receipts enter. The hard part is making capture reliable enough that the rest of the system is not starved of usable input: camera friction, bad light, retries, and a clear “this is in flight” feeling after upload.

Process — cloud-side work turns raw capture into structured fields a human can judge. Automation is allowed to be incomplete. The product rule is honesty about uncertainty, not a fake 100% parse rate.

Review — the person can correct what automation got wrong before it becomes “truth.” This is the load-bearing stage. Without a review path, every extraction error becomes a permanent budget lie.

Insights — only after review (or an explicit accept) does categorized spend become something you can read and act on. Insights are a consequence of trusted records, not a substitute for them.

Failure modes are part of the design, not footnotes. Capture can be rejected or retried. Processing can stall, fail, or land in a needs-review state. Review can send a receipt back into the loop. Insights only read from records that have crossed the trust gate.

That is the public architecture: a pipeline with a human checkpoint, not a feature laundry list and not a reverse-engineering of the private implementation.

Product flow: Capture, Process, Review, Insights, with a trust gate at Review and a retry loop from Review back to Process
Product loop with an explicit trust gate—automation proposes, humans confirm, insights only read trusted records.

Decisions

Full-stack ownership. For a product this small, splitting “mobile person / API person / ops person” would have slowed learning. Shipping meant holding the whole contract in one head—especially the places where money, auth, and lifecycle meet.

Human-in-the-loop over magic OCR. Extraction is a means. Trust is the product. I optimized for a complete path users can finish: capture → process → review → insights, with review as a first-class stage rather than a hidden admin tool.

Lifecycle before pretty dashboards. A receipt that is still processing must not look like a settled expense. Explicit states beat silent overwrites when automation is fallible.

Money as integer cents in spirit. Floating-point “almost right” totals are how personal-finance tools lose credibility. The rule is: never let display convenience invent precision the data does not have.

Typed mobile contracts. The app and API share explicit shapes so field drift shows up as a type error, not a silent bad total or a missing status.

Production ops early. Hosting, scheduled jobs, error tracking, secrets, and private access landed before the product was “done,” so the path could stay up while the hard edges got fixed.

Evidence-based mobile performance. When Android jank appeared under load, I measured with gfxinfo-style frame data and fixed real bottlenecks instead of guessing at list virtualization folklore.

Results

There is a working product path from mobile capture through cloud processing and human review into categorized spend insights—not a slide deck and not a single-screen OCR demo.

Production baseline is real: hosted API, scheduled work, error tracking, secrets management, and private networking where needed. Auth is wired for real users, not a hardcoded demo account.

The interesting proof is operational, not theatrical: receipts can be in flight without pretending they are settled; review can correct automation; insights only consume what has earned trust.

I treat this write-up as a public product case study. The implementation remains private while the app is in development. The goal is to show product judgment and full-stack ownership—especially around trust, money, lifecycle, and ops—not to publish an internal design doc.

⚡ accent mode unlocked