Spending Page¶
Route: / (index.html)
Nav label: Spending
Last Updated: 2026-08-11
What It Does¶
The landing page. A two-period spending comparison, a category table, a YTD table, a 12-month sparkline, and the income to spending Sankey.
/bank, /purchases, and /trends are 302s back here — they were separate pages once and are now
sections of this one.
Period Selection¶
Not a date range picker. The bar at the top holds two independent year + month pairs, Period 1 and Period 2, and the whole page renders as a comparison between them.
| Control | Populated by |
|---|---|
p1Year / p1Month |
GET /api/available-periods |
p2Year / p2Month |
same |
The mobile menu carries duplicate p1YearMobile / p1MonthMobile / p2YearMobile /
p2MonthMobile selects, because the period bar does not fit in the phone navbar.
GET /api/latest-data-period drives the stale-data banner. When the newest bank_transactions row
predates the current calendar month, the banner says so — otherwise the current month reads as near
zero spend and looks like a bug rather than missing statements.
Sections¶
Hero Metrics¶
Four cards, all from GET /api/overview.
| Card | Content |
|---|---|
| Selected Period | Total spend for Period 1 |
| Prior Period | Total spend for Period 2 |
| vs Prior Period | Difference, with a percentage badge |
| Avg Order Value | Mean order value |
/api/overview accepts start_date and end_date for Period 1, and compare_start / compare_end
for Period 2. When the compare dates are omitted it computes them: a full calendar month in
Period 1 compares against the previous calendar month, anything else compares against the
immediately preceding window of equal length.
Category Table¶
Side-by-side per-category totals for both periods, not a grid of cards. Column groups are labelled
catP1Header and catP2Header. Two controls sit in the section header:
- Category filter — a multi-select dropdown, with an All toggle
- Hide zeros — drops categories with no activity in either period
Clicking a category opens the drilldown modal: per-vendor totals plus a monthly trend, from
GET /api/category-drilldown and GET /api/category-transactions/<category>.
YTD Spending by Category¶
Year-to-date totals per category with budget comparison, from GET /api/ytd-by-category. Shares the
budget data with the Budget page.
Sparkline¶
12-month rolling spend trend, Plotly, from GET /api/overview.
Income → Spending (Sankey)¶
900px Plotly Sankey. See Sankey Architecture.
- CC Detail / Combined CCs toggle, client-side, no extra API call
- Powered by
GET /api/sankey?start_date=X&end_date=Y - The Sankey's date filter is month-granular while everything above is day-granular, so on a partial month the two will not agree
API Endpoints Used¶
| Endpoint | Purpose |
|---|---|
GET /api/available-periods |
Year/month options for both period pickers |
GET /api/latest-data-period |
Newest transaction month, drives the stale banner |
GET /api/overview |
Hero metrics, category totals for both periods, sparkline |
GET /api/ytd-by-category |
YTD table with budget comparison |
GET /api/sankey |
Sankey diagram |
GET /api/category-drilldown |
Per-vendor breakdown for a category |
GET /api/category-transactions/<category> |
Transaction list for the drilldown modal |
GET /api/receipt-detail/<id> |
Receipt detail modal |
POST /api/sync |
Trigger an on-demand order sync |
The reconcile panel moved
index.html still contains a #page-reconcile div, but reconciliation has its own page and its
own template. See Reconcile Tab.