Net Worth Page¶
Route: /money (money.html)
Nav label: Net Worth
Last Updated: 2026-08-11
What It Does¶
Total financial position across all tracked accounts. Balances come from the most recent
account_balances row per account, not live bank data.
/sankey redirects here, but the Sankey diagram is not on this page. See
Sankey Architecture.
Grouping¶
Accounts are grouped by accounts.display_group, and the net worth formula is that grouping, not a
simple assets-minus-liabilities split:
| Group | Contents |
|---|---|
cash |
Checking, savings, money market |
debt |
Credit cards, mortgage. Subtracted |
investments |
Brokerage, 529 |
retirement |
Traditional IRA, Roth IRA |
Only is_active = true accounts are included. Note that the formula also sums a savings group,
which no account currently uses — the savings accounts sit under cash. The term is inert today but
would double-count if an account were ever assigned display_group = 'savings'.
Sections¶
Net Worth Banner¶
Single total, plus per-group subtotals from GET /api/net-worth.
Account Balances Table¶
One row per active account: name (or nickname), institution, latest balance, as_of_date, and the
source of that balance (statement upload vs manual entry).
Balances older than 45 days get a stale badge. The threshold is a client-side constant in
money.html, not a server field.
Account nicknames are editable inline via PATCH /api/accounts/<id>/nickname.
Net Worth Trend Chart¶
GET /api/money-history returns one point per month that has any account_balances data. For each
month it takes the latest balance per active account as of that month end via a lateral join, then
sums by display_group. An account with no balance recorded before a given month end contributes
nothing to it, which is why early months are lopsided.
Leading months were trimmed once, and the underlying shape remains
Nov 2025 to Apr 2026 showed investments and retirement at zero because no Edward Jones statements had been loaded yet, producing a jump from roughly $20k to $1.96M. Those months were trimmed 2026-07-08. The chart still starts at the first month with complete coverage, so the earliest points are only as complete as the statements behind them.
API Endpoints Used¶
| Endpoint | Purpose |
|---|---|
GET /api/net-worth |
Latest balance per account grouped by display_group, plus the net worth total |
GET /api/money-history |
Monthly net worth series for the trend chart |
PATCH /api/accounts/<id>/nickname |
Rename an account for display |
How Balances Get Here¶
Two paths, both recorded in account_balances with a source and a source_file:
- Statement upload — the parser extracts the ending balance and calls
upsert_account_balance() - Manual entry — the Statements page, for accounts with no parser
The page shows the most recent balance per account. It does not average or interpolate. If a statement has not been loaded in two months, that account's balance is two months stale.
A missing account row means a silently skipped balance
upsert_account_balance() matches on institution + last4 + type. When no accounts row matches
it logs a WARN and skips, and the upload response reports success. The balance simply never
appears. Insert the account first — see Data Sources.