WealthView Architecture & Feature Cluster Baseline
This document serves as a high-level technical baseline for developers and AI agents working on the WealthView platform. It details the architecture, feature sets, algorithms, and design decisions to provide context for future enhancements.
1. System Overview & Architecture
WealthView is a self-hosted, multi-tenant personal finance application.
High-Level Architecture
- Frontend: React 19 SPA built with TypeScript, Vite, React Router, and Recharts/D3 for data visualization.
- Backend: Java 21+ with Spring Boot 3.5, providing a stateless REST API.
- Data Persistence: PostgreSQL 16+ accessed via Spring Data JPA (Hibernate 6+). Flyway handles schema migrations.
- Caching: Caffeine cache is utilized for fast retrieval of balances, holdings, and projection parameters.
- Deployment: Containerized via Docker Compose, utilizing Nginx as a reverse proxy (handling TLS and static assets).
Monorepo Structure
The codebase utilizes an npm workspace monorepo:
frontend/: React SPA.mobile/: React Native mobile application.shared/: Cross-platform utilities consumed by both web and mobile.backend/: Maven multi-module architecture:
wealthview-api: Controllers, Security, Exception Handling.wealthview-core: Domain models and business logic.wealthview-persistence: JPA entities and Flyway migrations.wealthview-import: OFX/CSV parsers and Finnhub client.wealthview-projection: Retirement modeling engine.wealthview-app: Spring Boot bootstrap and config.
2. Tenancy, Auth & Security
Tenant Isolation
Isolation is enforced at the row-level within a single Postgres database. Every table (except tenants and prices) contains a tenant_id foreign key. A Spring Security filter extracts the tenant_id from the user's JWT and enforces this boundary globally across all repository queries, ensuring cross-tenant data spillage is impossible.
Authentication & Role-Based Access Control (RBAC)
- Auth: Stateless JWTs (JSON Web Tokens). Passwords hashed using bcrypt.
- Registration: Invite-code gated. A
super-admin generates invite codes. - Roles:
admin (Full CRUD + tenant user management)member (Full CRUD on financial data, no user management)viewer (Read-only access)
Roles are enforced via endpoint-level Spring Security annotations.
3. Core Feature: Investment Portfolio Tracking
Holdings Auto-Computation Algorithm
Rather than storing static holding records, holdings are dynamically driven by transaction history.
- Algorithm: When a transaction (buy, sell, dividend reinvestment) is ingested, a core service recomputes the affected holding for that
account_id + symbol. It aggregates all historical transactions chronologically to calculate the current quantity and cost_basis. - Manual Overrides: Users can manually override a holding (e.g., when full transaction history from a legacy broker isn't available). These are flagged with
is_manual_override = true. If subsequent automated imports conflict with an overridden holding, the system issues a warning rather than blindly overwriting. - Alternatives Considered: Event-Sourcing (CQRS) was an alternative, but rebuilding state strictly from a transaction ledger synchronously is simpler and highly performant with current database indexes and Caffeine caching.
Import Deduplication Algorithm
- Algorithm: CSV and OFX imports utilize a SHA-256 content-hashing algorithm. For each transaction, a hash is generated based on
date, amount, and normalized_description (and potentially an institution-provided FITID for OFX). This hash is stored in the import_hash column. - Execution: During batch import, the system does an
IN query against existing hashes in the account to silently drop duplicates, ensuring safe idempotency during repeated imports.
Valuation & Live Price Feeds
- Architecture: The
wealthview-import module runs a Spring @Scheduled job to fetch daily close prices for all held symbols via the Finnhub API. - Historical Backfill: Triggered by a
NewHoldingCreatedEvent, the system queries Finnhub to backfill 2 years of trailing prices, allowing for rich historical net-worth charting immediately upon adding an asset.
4. Core Feature: Rental Property Management
Valuation & Cash Flow Modeling
- Data Model: Tracks
properties alongside property_income (rent) and property_expenses (mortgages, taxes, capex, maintenance). - Algorithms:
- Cash Flow: Aggregates income and expenses on a monthly/annual basis.
- ROI & Cap Rate: Dynamically calculated by combining trailing 12-month net operating income (NOI) against the user-provided
current_value or original purchase_price.
- External Integration: Zillow valuation scraping is referenced as a feature, which likely requires robust error handling and proxying due to anti-scraping measures.
5. Core Feature: Retirement Projections
This is the most computationally heavy module (wealthview-projection).
Deterministic Engine
- Algorithm: A year-by-year loop projecting future net worth. It compounds
initial_balance + annual_contribution by a fixed expected_return and adjusts for an inflation_rate. - Drawdown Strategy: Simulates withdrawal orders (e.g., Taxable -> Tax-Deferred -> Roth) applying standard tax bracket logic to determine gross withdrawal requirements.
Monte Carlo & Guardrail Optimizer
- Algorithm (Block-Bootstrap Returns): Rather than assuming a normal distribution (which underestimates fat-tail risk), the Monte Carlo engine samples contiguous historical "blocks" of market returns (e.g., actual S&P 500 monthly returns from 1970-1975) to generate thousands of randomized but historically correlated sequences.
- Guardrail Spending (Guyton-Klinger): The optimizer adjusts withdrawal rates dynamically during the simulation. If a portfolio drops severely (hitting a "guardrail"), the withdrawal rate is cut by a percentage. If it surges, the withdrawal rate increases.
- Alternatives Considered: Standard parametric Monte Carlo (Log-normal distribution) is easier to implement but less realistic for sequence-of-returns risk. Block-bootstrapping requires a curated historical dataset to reside in the database or memory.
6. Developer Guidelines & Configuration
- Secrets: Managed entirely via environment variables.
application.yml uses ${VAR} references. The ProductionConfigValidator prevents booting if sentinel dev values leak into production. - CI/CD Pipeline: Gitleaks pre-commit hooks and GitHub Actions workflows block secrets from entering source control.
- API Conventions: Standard REST
/api/v1/*. JSON payloads use snake_case. Standard envelope for pagination.