- Add budget editing: updateBudget() API, edit button on budget cards,
BudgetFormModal adapted for create/update (category locked on edit)
- Remove permanently-broken POST /auth/totp/verify stub and its unused
TOTPVerifyRequest schema
- Wire getHoldingTransactions() to AssetDetail page — transaction history
table now shows above the candlestick chart, sorted newest-first
- Fix multi-currency net worth in account_service: account balances are
now converted to base_currency via ExchangeRate table before summing
- Replace silent bare pass exception handlers with logger.warning() in
transactions.py (OCR/AI pipeline) and price_feed_service.py (search)
— ValueError in date/number regex parsing left silent (control flow)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add four portfolio charts: allocation donut by holding, allocation
donut by asset type, cost basis vs current value bar, return % bar
- Fix asset search to use yf.Search() full-text instead of ticker-only
lookup — name searches like "vanguard ftse all world" now work
- Fix holding creation double-quantity bug: holdings now created with
quantity=0 so buy transaction is sole source of quantity/cost basis
- Add per-share / total price toggle in Add Holding modal with live
calculated equivalent shown as you type
- Add ErrorBoundary in AppShell so render errors show a message instead
of a blank page
- Fix donut charts using || instead of ?? when falling back from
current_value to cost_basis_total (0 was not falling through ??)
- Allow HoldingCreate.quantity >= 0 (was gt=0) to support zero-init
- Fix error display for Pydantic v2 array-of-objects validation errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>