All work

Personal finance automation

From transaction alerts to a daily spending view.

Personal finance mobile app showing activity graphs alongside budget headroom and envelope widgets

One alert, one shared path.

  1. 01

    Receive

    An incoming transaction alert reaches the edge service.

  2. 02

    Validate

    Check the incoming message and parse its transaction information.

  3. 03

    Reconcile

    Deduplicate the record and use the reported balance as the anchor.

  4. 04

    Update

    Refresh the mobile view, widgets, and applicable notifications.

The challenge.

A useful daily spending view should stay current without manually entering every transaction. Incoming alerts also need to survive duplicate delivery, missed messages, and background execution limits.

I built a personal app around bank-reported balances, shared ingestion logic, and a small event-driven backend.

The boundaries.

  • Use transaction information without giving the app a way to move money.
  • Deduplicate alerts arriving through more than one ingestion path.
  • Separate administrative access from read-and-log capabilities.
  • Keep mobile widgets and notifications current outside an active app session.

How it fits
together.

A TypeScript service runs on Cloudflare Workers with Hono, Turso/libSQL, and Drizzle. Email and HTTP ingestion share transaction parsing and deduplication. Scheduled work and background notification delivery feed an Expo client and widgets. The implementation checks incoming mail authentication verdicts before ingestion; this is a personal product, with no money-movement functionality.

The decisions
behind the details.

01

Anchor to the reported balance

Accumulating transactions indefinitely makes every missed event matter forever. A bank-reported balance gives the product a fresh reconciliation point.

Tradeoff
A stale alert must remain distinguishable from a current balance.
02

Share the ingestion path

Email, HTTP, and scheduled work should agree on what a transaction means. Shared parsing and deduplication make a second delivery a repeat, rather than a second expense.

Tradeoff
Changes to parsing need regression checks against the existing event formats.
03

Separate capabilities

A device that reads and logs transactions does not need every administrative action. Scoped tokens keep those responsibilities separate.

Tradeoff
Clients must handle a denied operation explicitly instead of assuming every token has full access.

Mobile AI agents

Next case study