Project Overview
A privacy-first, offline-capable personal investment portfolio tracker. All financial data is encrypted locally in the browser using AES-256-GCM โ no portfolio data ever touches a server. A lightweight Cloudflare Worker acts solely as a CORS proxy for Yahoo Finance market data with zero knowledge of user data. No authentication, no backend database, no recurring cost.
Key Features
- Encrypted Vault โ Binary vault format with FOLI magic bytes. PBKDF2-HMAC-SHA256 at 600K iterations (~300-800ms unlock). AES-256-GCM via Web Crypto API. CryptoKey marked non-extractable, zeroed on lock.
- Dashboard & Charts โ Summary metric cards (total value, daily G/L, unrealized G/L, realized G/L YTD, income YTD, cash). Portfolio value line chart, asset allocation donut, monthly income bar chart. Account filter pills + time range selector (1D-All). Charts are presentational-only (data via props).
- Positions & Tax Lots โ Open positions table with expandable per-lot breakdown. Tax lot table with acquired date, cost basis, unrealized G/L, wash sale flag. Cost basis methods: FIFO, LIFO, Specific ID, Average Cost.
- Transaction Management โ Full CRUD with type badges (Buy, Sell, Dividend, Interest, Transfers, Journals). Virtualized table via TanStack Table for large datasets.
- CSV Import โ Bank-specific parsers for Schwab, Optum, and generic CSV. Schema validation, deduplication by external ID.
- Google Sheets Sync โ OAuth 2.0 via Google Identity Services. Auto-writes account balances to a configurable Google Sheet.
- Income View โ Year-over-year table, income by security, monthly calendar grid. Account and year filters.
- PWA & Dark Mode โ Installable with standalone manifest. Service Worker caches market data (NetworkFirst, 100 entries, 1-day TTL). Responsive: collapsible sidebar on desktop, bottom tab nav on mobile.
- Deterministic Ledger Engine โ Pure function rebuilds all derived data (positions, lots, income) from raw transactions every time. FIFO lot matching, realized G/L computation, roundCurrency() to avoid floating-point drift.
Technical Architecture
Pages โ Pinia Stores โ Chart Components (presentational only)
โ
Ledger Engine (pure function: recalculateDerivedDataFromTransactions())
โ
Vault Store (encrypt/decrypt via Web Crypto API)
โ
Encrypted .iFolio file (binary: magic bytes + salt + IV + ciphertext)Key architectural decisions: charts never import stores directly (data via props), all types in app/types/, ledger engine is a deterministic pure function, Cloudflare Worker has zero knowledge of user data.
Project Evolution
Phase 1 โ Foundation: Nuxt 4 SPA scaffold, encrypted vault (FOLI binary format, PBKDF2 + AES-256-GCM), vault I/O via File System Access API + download fallback, Cloudflare Worker skeleton.
Phase 2 โ Market Data Pivot: Originally built Schwab OAuth integration. Pivoted to Yahoo Finance โ eliminated OAuth friction, 60% less Worker code, no KV dependency.
Phase 3 โ Dashboard & Views: Dashboard with metric cards and charts, positions with tax lot breakdown, full transaction CRUD, income view, settings.
Phase 4 โ Polish & Launch: PWA installable with Service Worker, CI/CD pipelines (GitHub Actions โ lint โ typecheck โ test โ deploy), Google Sheets sync, responsive design, dark mode.
Key Technical Challenges Solved
- Deterministic ledger engine that rebuilds all derived data from raw transactions on every mutation โ ensures consistency.
- Browser-compatible strong encryption via Web Crypto API โ PBKDF2 at 600K iterations runs entirely client-side.
- File System Access API for native file save/open on Chromium, with download-based fallback for Firefox/Safari.
- Schwab OAuth โ Yahoo Finance pivot โ removed all auth infrastructure, simplified Worker to transparent proxy.
- Zero
any type policy โ every value typed explicitly,unknown + narrowing enforced in CI.
๐ค AI-Driven Development
This project was built entirely through AI pair programming โ no traditional outsourcing, no large team. It began with careful prompt-by-prompt guidance, testing each feature incrementally and refining the codebase one interaction at a time.
As the codebase matured, the development workflow scaled to multiple AI agents working concurrently โ one refactoring the ledger engine while another built chart components, a third set up CI/CD pipelines, all coordinated through clear interfaces and typed contracts. What started as guided iteration became a parallel multi-agent engineering process.
Tech Stack
Frontend
- Nuxt 4 (SPA)
- Vue 3
- TypeScript
- Pinia
- Tailwind CSS 4
- Nuxt UI 4
Charts & UI
- ApexCharts + vue3-apexcharts
- TanStack Table v8
- Lucide + Simple Icons
Backend
- Cloudflare Worker (TypeScript)
- Yahoo Finance API
Security
- Web Crypto API
- PBKDF2-HMAC-SHA256
- AES-256-GCM
Infrastructure
- GitHub Actions (CI/CD)
- @vite-pwa/nuxt
- GitHub Pages
- Cloudflare Workers
Testing
- Vitest
- @nuxt/test-utils
- @cloudflare/vitest-pool-workers