Andrew Parra ES

Lab · Personal finance

Cupel (FinanceOS)

A self-hosted personal finance app that syncs bank transactions and puts net worth and goal progress first.

Status
Live · private
Who uses it
Andrew. It is built to support more than one account, with sign-in and billing, but today it is his own tool.
Built with
Node.js + Express · SQLite (one file per user) · Plaid · Stripe · Claude API · Capacitor · Render

The card payment planner, in its fixed order

Example

Example paycheck $1,200

  1. 1
    Safety buffer$500 of $500 · full
  2. 2
    Minimums, each card$180 of $180 · full
  3. 3
    Extra payments$520 · what’s left

Shows its working: 1,200 − 500 buffer − 180 minimums = 520 extra

Duplicate-charge catch Example

Coffee shop$4.75pending
COFFEE SHOP #12$4.75postedDuplicate

Net worth over time Example

Account added: not a gain
“Works in a fixed order: safety buffer, then minimums, then extra payments, and shows its working.” Money only moves to the next step once the one before is full.

The problem

Most finance apps lead with spending categories. Cupel leads with the long-term picture, net worth and goals, and treats cashflow, tax deductions and debt as the levers that move it. The point is numbers trustworthy enough to act on.

How it works

Bank sync

Accounts connect through Plaid Link, so the app never sees a bank password. Transactions sync incrementally when Plaid signals new data.

Cashflow that separates sure from likely

“Guaranteed” income is kept apart from estimated income, so must-pay decisions only count money that is certain.

Card payment planner

Works in a fixed order: safety buffer, then minimums, then extra payments, and shows its working.

Goals with a verdict

Each goal shows the monthly amount needed against what is actually spare, and flags goals competing for the same dollar.

Net worth over time

A daily snapshot, with adding or removing an account recorded so it never reads as a gain or a loss.

Duplicate charges

Catches double charges across pending and posted transactions, refunds and merchant-name variants.

Plus

Budgets, subscription and price-increase detection, a retirement planner, and push alerts kept to things that are urgent and actionable.

Where AI fits

  • Tax-deduction pre-sort: each transaction is tiered likely / possible / no for review, never filed.
  • “Ask” answers questions about your own data; “Assistant” turns a plain-English scenario into proposed plan changes.
  • All Claude calls go through one wrapper with retries, a daily spend cap and usage logging.

Guardrails

Locked by default

Every route needs a login, and the app refuses to start without a password configured.

Encrypted bank tokens

Bank access tokens are encrypted at rest (AES-256-GCM) with a separate key per user.

AI never does the maths

Ask’s tools are read-only, the database computes every figure, and Assistant changes need an explicit click.

Not tax advice

Deduction tiers are a pre-sort for a human to review. Nothing is filed automatically.

Engineering notes

One database file per user

Instead of a user column in every table. With hundreds of hand-written queries, a file boundary can’t be forgotten, and export or delete becomes a file operation.

“The model picks the query, the database computes, the model explains”

So every number in an AI answer comes from the database, not the model.

Native sign-in

The phone shells can’t keep a web cookie, so the same signed session travels as a bearer token to allow-listed app origins only.

App Store rules designed in

No purchase links inside the native app, and the experimental trading feature is removed from client builds; the build fails if any trace survives.

What’s next

iOS and Android builds exist but are not submitted. Next is the paperwork for the stores: a legal entity, developer accounts, public privacy and terms pages.