whisper-money/app/Http/Controllers
Víctor Falcón 9c3c4d573e
feat(analysis): per-category 12-month spending drawer (#519)
## Summary

Adds a **category-analysis drawer** so you can see how much you spend on
a single category, month by month, over the last 12 months — answering
"am I spending more or less on food delivery?".

Reachable via an **Analyze** button on three cards:
- Dashboard → Top spending categories
- Cashflow → Income Sources
- Cashflow → Expense Categories

Each button opens a shared drawer with a full-width category chooser
(all categories) and a 12-month stacked bar chart.

## Chart semantics
- X = last 12 rolling months (gaps filled with zero). Y = user display
currency.
- Stacked segments = the chosen category's immediate children
(grandchildren rolled in) + a **Direct** segment (spend on the parent
itself) + an **Other** segment (children beyond the top 6, ranked by
total).
- A leaf category renders a single series named after the category.
- Amounts convert to the user currency and **net per month**, oriented
by category type so the expected direction reads as a positive bar; an
against-grain month (e.g. refunds > spend) dips below zero.
- Colors use the theme-aware chart palette (same as the net-worth
chart).

## Summary stats
Two glowing cards above the chart: **Monthly average** and **Trend**
(recent 6-month average vs earlier 6-month average; null when there's no
earlier baseline).

## Persistence
Each widget remembers its own chosen category in `localStorage`
(category only), prefilling the first category of its list otherwise; a
remembered-but-deleted category falls back gracefully.

## Tests
- 11 Pest feature tests (rollup, Direct/Other, net-with-refunds,
12-month window, currency conversion, income orientation, summary
average + trend).
- 5 vitest tests for the prefill/persistence precedence.
- es.json keys added.
2026-06-11 09:52:53 +02:00
..
Api feat(analysis): per-category 12-month spending drawer (#519) 2026-06-11 09:52:53 +02:00
Auth fix: verify email via signed link without requiring login (#490) 2026-06-05 10:01:32 +02:00
OpenBanking feat(open-banking): finalize bank connection without a session via state token (#498) 2026-06-06 12:12:07 +02:00
Settings refactor(api): standardize serialization via model $hidden (#492) 2026-06-05 13:57:34 +02:00
Sync refactor(api): standardize serialization via model $hidden (#492) 2026-06-05 13:57:34 +02:00
AccountBalanceController.php feat: investment benefits — show gains/losses on investment accounts (#140) 2026-02-23 13:59:10 +01:00
AccountController.php refactor(api): standardize serialization via model $hidden (#492) 2026-06-05 13:57:34 +02:00
BudgetController.php refactor(api): standardize serialization via model $hidden (#492) 2026-06-05 13:57:34 +02:00
CashflowController.php refactor(api): standardize serialization via model $hidden (#492) 2026-06-05 13:57:34 +02:00
Controller.php Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
DashboardController.php feat: expand parent categories inline in breakdowns (#486) 2026-06-04 11:19:21 +02:00
EncryptionController.php Remove unused controllers and routes (#11) 2025-12-04 08:48:17 +01:00
LoanDetailController.php feat(loans): backfill historical balances on loan creation (#322) 2026-04-24 13:09:34 +01:00
OnboardingController.php feat(open-banking): finalize bank connection without a session via state token (#498) 2026-06-06 12:12:07 +02:00
ReEvaluateTransactionRulesController.php refactor(api): standardize serialization via model $hidden (#492) 2026-06-05 13:57:34 +02:00
RealEstateDetailController.php feat(accounts): add real estate asset tracking (#241) 2026-03-24 10:21:32 +00:00
RobotsController.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
SitemapController.php SEO landing page 2025-11-25 11:33:11 +01:00
SubscriptionController.php fix: allow managing canceled connections (#417) 2026-05-22 10:52:50 +01:00
TransactionController.php fix(transactions): prevent crash when sorting by nullable column (#501) 2026-06-06 17:23:21 +02:00
UserLeadController.php feat: verify waitlist leads (#285) 2026-04-14 11:26:01 +01:00