Finance‑Guru™ – Technical Briefing


The Problem

Financial analysts must juggle dozens of web tools, spreadsheets, and manual calculations to evaluate a single portfolio decision. The resulting workflow is error‑prone, hard to audit, and slows down investment execution.


What This Does

Finance‑Guru provides a self‑contained “family‑office” stack that stitches together data ingestion (Plaid), a set of Python‑based quantitative tools, and a UI built with Next.js/React.

  • The Plaid integration lives under apps/plaid-dashboard/engine/src/providers/plaid/ – e.g. plaid-api.ts creates link tokens, exchanges public tokens, and fetches accounts/balances.
  • Core analytics are in src/ – models such as src/models/itc_risk_inputs.py and src/models/momentum_inputs.py expose Pydantic‑validated inputs, while the CLI wrappers in src/utils/ run the 11 analysis tools (risk, momentum, correlation, etc.).
  • The front‑end UI (apps/plaid-dashboard/dashboard/src/) consumes the API defined in apps/plaid-dashboard/dashboard/src/lib/api.ts (functions saveConnectionLocally, createLinkToken, exchangePublicToken, getAccounts, …) and renders account tables, transaction lists, and link‑button components.

How It Is Wired

  1. Entry point – The Docker compose file apps/plaid-dashboard/docker-compose.yml starts the Node/Next.js server (npm start in apps/plaid-dashboard/dashboard) and the Flask engine (python -m uvicorn apps.plaid-dashboard.engine:app).
  2. API bootstrap – apps/plaid-dashboard/dashboard/src/lib/api.ts imports getEngineUrl (from utils.ts) and calls the Plaid‑engine endpoints (/create-link-token, /exchange-public-token, /accounts).
  3. Engine request flow – A request to /accounts triggers apps/plaid-dashboard/engine/src/routes/accounts.ts → plaid-api.ts.getAccounts → transform.ts.transformAccount → returns JSON to the UI.
  4. Database touch – apps/plaid-dashboard/engine/src/services/sync-service.ts (functions createConnection, syncTransactions) uses Prisma (PrismaService) to read/write the BankConnection and Transaction tables defined in apps/plaid-dashboard/engine/src/db/schema.ts. The static call graph shows a single outbound DB edge from the main hook (.claude/hooks/error-handling-reminder.ts) through analyzeFileContent.
  5. Core analytics – CLI commands (e.g. uv run python src/utils/momentum_cli.py TSLA) import models from src/models/ and invoke calculation classes; these modules have high instability (src/ui/services/analysis_runner imports 12 others) and are the most connected nodes, meaning changes here ripple widely.
  6. Exception handling – Broad except: blocks appear in src/config.py, src/strategies/optimizer.py, and src/ui/services/portfolio_loader.py, swallowing errors before they reach the API layer.
  7. Duplication – Identical 6‑line snippets are repeated across 40 files (e.g., error‑handling hooks and UI pages), inflating maintenance cost.

No CI configuration is present, so the above flow is not validated automatically. The import graph contains 97 internal modules, 105 edges, zero cycles, indicating a clean dependency shape but a few high‑impact hubs.


How To Use It

# 1. Clone
git clone https://github.com/moses-y/Finance-Guru.git
cd Finance-Guru

# 2. Build containers (Dockerfile present, docker‑compose orchestrates services)
docker compose -f apps/plaid-dashboard/docker-compose.yml up --build -d

# 3. Install front‑end deps
cd apps/plaid-dashboard/dashboard
npm ci   # uses package-lock.json

# 4. Provide runtime secrets (copy the example)
cp .env.example .env          # required by the Flask engine
cp apps/plaid-dashboard/.env.example apps/plaid-dashboard/.env

# 5. Start the UI (still in the dashboard folder)
npm run dev   # runs Next.js on localhost:3000

The repository does not contain a top‑level Makefile or a uv‑managed Python lockfile; the Python side relies on the requirements.txt‑style lock in .claude/hooks/package-lock.json and the uv commands shown in the README snippets.


Real‑World Use

A portfolio manager runs the UI, clicks “Link Plaid”, which triggers createPlaidLinkToken → Plaid OAuth flow → exchangePublicToken. The engine stores the connection (sync-service.createConnection) and periodically calls syncTransactions, which transforms raw Plaid data (transform.ts) into the normalized Transaction schema. The manager then opens the Risk tab, which runs src/analysis/risk_metrics_cli.py against the stored transactions, delivering a Sharpe ratio, VaR, and compliance alerts—all in one session.


Code Health & Issues

  • High – Missing CI – No .github/workflows/; 97 source files are never built/tested automatically.
  • High – No build gate for Docker image – apps/plaid-dashboard/docker-compose.yml deploys without a CI‑verified image.
  • Medium – No Dependabot – 7 manifest files exist but no automated version‑bump config.
  • Medium – Duplicated code blocks – 215 identical 6‑line snippets across 40 files (.claude/hooks/*.ts, UI pages).
  • Medium – Broad exception handling – except: used in src/config.py, src/strategies/optimizer.py, src/ui/services/portfolio_loader.py.
  • Medium – Deep nesting – Files src/models/itc_risk_inputs.py, src/models/momentum_inputs.py, src/models/risk_inputs.py have indentation depth 6, making logic hard to follow.
  • Medium – Oversized files – src/strategies/optimizer.py (632 LOC) and .claude/skills/FinanceReport/tools/ReportGenerator.py are monolithic.

All findings are derived from the static analysis output; no additional issues were inferred.


The Bottom Line

Finance‑Guru delivers a functional end‑to‑end Plaid‑driven portfolio analysis stack with a clear UI and a set of reusable Python analytics. The architecture is modular, but maintenance burden is high due to duplicated logic, broad exception handling, and oversized modules. Immediate payoff can be gained by adding CI/CD, tightening exception granularity, and refactoring the most‑connected hubs (analysis_runner, Plaid provider). The repo is suitable for teams that need a quick prototype of an AI‑augmented family office but should allocate resources to improve test automation and code hygiene before scaling.