What's Changed
A big release for planning. Goals get a full editorial redesign with a save-up projection engine and a brand new Retirement Planner backed by a Monte Carlo Risk Lab. The AI assistant can now read your Health Center, run inline CSV imports, and remember attachments. Symbol mapping validates in real time per provider, custom providers can finally point at self-hosted URLs, and dozens of fixes land across activities, holdings, mobile, and device sync.
✨ Highlights
🎯 Goals & Retirement Planning
- Editorial goals dashboard with cover cards and a redesigned widget
- Save-up projection engine with milestones, projection chart, and tax-aware funding
- Brand new Retirement Planner — a goals-first retirement experience with traditional vs FIRE goal types and default ages
- Risk Lab: Monte Carlo (5k runs by default), stress tests, sensitivity heatmaps, layout-aware loading skeletons
- Backend overhaul: new retirement simulation engine, tax bucket columns, consolidated goal migrations, dedicated
RetirementPlanDTO - Not-financial-advice disclaimer on the retirement dashboard
🤖 AI Assistant
- Inline CSV import — assistant infers mappings; the app drives parse → validate → import in chat using the same review grid as the manual wizard, with bulk skip / unskip / force-import
- New
get_health_statustool — assistant can read Health Center issues and guide you to fixes - New
get_cash_balancestool — per-account, per-currency cash positions - Attachments persisted across the session (CSV / image / PDF) with bounded session caches and CSV redaction
- Polished UI: attachment chips, continuation loader, activity confirmation, compact tool cards, redesigned tool fallback
✅ Symbol Mapping Validation
- Real-time validation in the Market Data tab with provider-specific feedback (Yahoo Finance, Börse Frankfurt, custom providers)
- Debounced spinner → green check / red error icon per row
preferred_providerthreaded through Rust → Tauri → Axum → TS so validation hits the exact provider configured- Non-blocking warning toast when saving with invalid mappings
🔌 Custom Market Data Providers
- Redesigned editor with click-to-map — the provider settings editor now shows a live preview pane of the fetched response next to your mapping fields; click any value (price, date, OHLCV, etc.) in the preview to instantly bind it to the matching field instead of typing CSS selectors or JSON paths by hand
- Self-hosted / private-network URLs supported — the SSRF-style URL gate is gone
- OHLCV mapping — open / high / low / volume paths across models, storage, templates, preview, and runtime
- ISO 8601 + Excel day-serial date detection
- Preview / runtime parity — shared browser-like headers, redirect handling, and template expansion (
{FROM}/{TO}/{currency}) so providers that test green also work at sync time
🩺 Health Center
- Negative balance details — first-negative date, cash balance, investment value, and likely cause per account; CASH accounts now show INFO instead of ERROR
- FX integrity — drawer lists each affected currency pair instead of just a count
- Price staleness now uses the asset's exchange MIC for timezone calculations
🔁 Activities & Transfers
- Link existing transfer activities — select two existing external transfers (one IN + one OUT) in the datagrid and click Link to retroactively pair them
- Transfer unlink flow — unlink linked pairs from the activity grid with confirmation
- Transfer In cost basis edit now pre-populates instead of failing validation
- Securities transfers display qty × price (not stored amounts)
- DRIP amount inference — DRIP rows without an amount compute from price × quantity
📊 Holdings & Dashboard
- Hide expired options toggle in the global Holdings filter (and mobile filter sheet); also filtered at the holdings service layer and from the assets settings view
- Top 7 dashboard holdings (up from 5), with persisted Symbol vs Name display option
- Account snapshot history tab
- ISIN on asset profile — shown in the About tab and editable in the General tab
- Dashboard performance % now matches the account page
🐛 Bug Fixes
- Crypto / FX symbol resolution for assets like BTC quoted in EUR (#814)
- Sell edit holdings warning (#861)
- Avg cost overwriting today's quote on manual holdings (#846)
- Holding weights for expired options
- FX rate direction hint in the activity form
- History chart Y-axis scaling for material moves
- Manual activity duplicate saves
- Mobile activity update validation and asset link guard
- Mobile chart drag triggering page swipes (asset profile, performance, income)
- Mobile device sync pairing dialog width
- Activity asset identity edge cases
- CSV import asset review timeout for large Options imports
- Asset (de)activation when positions close / reopen
- Metal symbols with weight suffix (exact troy ounce constant)
- AI
get_health_statustool payload simplified for LLM consumption - Sync table rebase + legacy goal / allocation payload migration on replay
- FX valuation parsing hardened
- Connect excluded-account sync copy clarified
- Docker Compose auth hash escaping (#865)
- AI CSV review hardened against stale state and per-account failures; live import session caches bounded
⚙️ Infrastructure & Performance
rust-toolchain.tomladded to lock Rust version across contributors and CI- Claude Code hooks for pre-commit / pre-push CI checks
- Decoupled retirement dashboard loading states
- Lighter risk-lab outcome calculations, delayed sensitivity maps
- Desktop foreground sync pauses while the window is unfocused
- Improved device sync liveness and pairing safety across desktop and web
🙏 Contributors
Thanks to everyone who contributed to this release: @afadil, @Jonjon-prog, @triantos, @marcoscale98, @loreboldo, @h1srf.
Full Changelog: v3.2.1...v3.3.0