# nathanblatter/finforge architecture

> Architecture diagram of the GitHub repository nathanblatter/finforge, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nathanblatter/finforge
- Repository: https://github.com/nathanblatter/finforge

## Overview

FinForge is a self-hosted personal-finance platform. Its main path is nightly Plaid/Schwab ingestion, privacy-conscious normalization into PostgreSQL, then API-backed dashboards and analysis; users also get AI coaching, alerts, reports, goals, watchlists and messaging. The UI’s API client, FastAPI routers and scheduled cron jobs are distinct access paths to shared data. Edges follow explicit README statements and the supplied import/call evidence; less-sampled feature wiring is left unasserted.

Main entry points: [`cron/main.py`](https://github.com/nathanblatter/finforge/blob/main/cron/main.py) (Scheduler), [`api/routers`](https://github.com/nathanblatter/finforge/tree/main/api/routers) (Finance endpoints), [`api/main.py`](https://github.com/nathanblatter/finforge/blob/main/api/main.py) (FastAPI application), [`cron/integrations/plaid_sync.py`](https://github.com/nathanblatter/finforge/blob/main/cron/integrations/plaid_sync.py) (Plaid sync)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["User interface"]
  node_ui["React dashboard<br/>[App.tsx]"]
  node_clientapi["API client<br/>[client.ts]"]
end

subgraph group_service["API services"]
  node_api["FastAPI application<br/>[main.py]"]
  node_auth["Authentication<br/>[auth.py]"]
  node_routers["Finance endpoints"]
  node_services["Finance calculations"]
end

subgraph group_sync["Scheduled data"]
  node_cron["Scheduler<br/>[main.py]"]
  node_plaid["Plaid sync<br/>[plaid_sync.py]"]
  node_schwab["Schwab sync<br/>[schwab_sync.py]"]
  node_normalize["Data normalization<br/>[deidentify.py]"]
end

subgraph group_storage["Shared finance data"]
  node_database[("PostgreSQL")]
  node_models["API data models<br/>[db_models.py]"]
  node_crondb["Cron data access<br/>[db.py]"]
end

subgraph group_features["Finance features"]
  node_spending["Spending &amp; budgets<br/>[spending.py]"]
  node_portfolio["Portfolio analysis"]
  node_coach["AI coach"]
  node_goals["Goal tracking<br/>[goal_engine.py]"]
  node_alerts["Alerts<br/>[alerts_engine.py]"]
  node_reports["PDF reports<br/>[reports.py]"]
  node_market["Market &amp; options<br/>[schwab.py]"]
  node_messages["iMessage delivery"]
end

node_person(("Finance user"))
node_plaidext{{"Plaid API"}}
node_schwabext{{"Schwab Trader API"}}
node_claude{{"Claude API"}}

node_person -->|"uses"| node_ui
node_ui -->|"requests data"| node_clientapi
node_clientapi -->|"calls HTTP API"| node_api
node_api -->|"registers routes"| node_routers
node_routers -->|"authenticates"| node_auth
node_routers -->|"queries data"| node_models
node_api -->|"uses PostgreSQL"| node_database
node_models -->|"maps schema"| node_database
node_cron -->|"runs sync"| node_plaid
node_cron -->|"runs sync"| node_schwab
node_plaid -->|"fetches accounts"| node_plaidext
node_schwab -->|"fetches portfolios"| node_schwabext
node_plaid -->|"normalizes records"| node_normalize
node_schwab -->|"normalizes records"| node_normalize
node_normalize -->|"persists records"| node_crondb
node_crondb -->|"reads and writes"| node_database
node_routers -->|"serves spending"| node_spending
node_routers -->|"serves analysis"| node_portfolio
node_services -->|"provides market data"| node_market
node_cron -->|"runs goal checks"| node_goals
node_cron -->|"runs alert checks"| node_alerts
node_cron -.->|"schedules reports"| node_reports
node_cron -->|"generates insights"| node_coach
node_coach -->|"requests completions"| node_claude
node_alerts -.->|"queues messages"| node_messages

click node_ui "https://github.com/nathanblatter/finforge/blob/main/ui/src/App.tsx"
click node_clientapi "https://github.com/nathanblatter/finforge/blob/main/ui/src/api/client.ts"
click node_api "https://github.com/nathanblatter/finforge/blob/main/api/main.py"
click node_auth "https://github.com/nathanblatter/finforge/blob/main/api/auth.py"
click node_routers "https://github.com/nathanblatter/finforge/tree/main/api/routers"
click node_services "https://github.com/nathanblatter/finforge/tree/main/api/services"
click node_cron "https://github.com/nathanblatter/finforge/blob/main/cron/main.py"
click node_plaid "https://github.com/nathanblatter/finforge/blob/main/cron/integrations/plaid_sync.py"
click node_schwab "https://github.com/nathanblatter/finforge/blob/main/cron/integrations/schwab_sync.py"
click node_normalize "https://github.com/nathanblatter/finforge/blob/main/cron/etl/deidentify.py"
click node_models "https://github.com/nathanblatter/finforge/blob/main/api/models/db_models.py"
click node_crondb "https://github.com/nathanblatter/finforge/blob/main/cron/db.py"
click node_spending "https://github.com/nathanblatter/finforge/blob/main/api/routers/spending.py"
click node_portfolio "https://github.com/nathanblatter/finforge/blob/main/ui/src/pages/PortfolioAnalysisPage.tsx"
click node_coach "https://github.com/nathanblatter/finforge/tree/main/api/services/agent"
click node_goals "https://github.com/nathanblatter/finforge/blob/main/cron/goal_engine.py"
click node_alerts "https://github.com/nathanblatter/finforge/blob/main/cron/alerts_engine.py"
click node_reports "https://github.com/nathanblatter/finforge/blob/main/api/routers/reports.py"
click node_market "https://github.com/nathanblatter/finforge/blob/main/api/services/schwab.py"
click node_messages "https://github.com/nathanblatter/finforge/blob/main/cron/imessage_delivery.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_ui,node_clientapi,node_person toneBlue
class node_api,node_auth,node_routers,node_services toneAmber
class node_cron,node_plaid,node_schwab,node_normalize,node_plaidext,node_schwabext,node_claude toneMint
class node_database,node_models,node_crondb toneRose
class node_spending,node_portfolio,node_coach,node_goals,node_alerts,node_reports,node_market,node_messages toneIndigo
```

## Components

### User interface

- [React dashboard](https://github.com/nathanblatter/finforge/blob/main/ui/src/App.tsx): `ui/src/App.tsx`
- [API client](https://github.com/nathanblatter/finforge/blob/main/ui/src/api/client.ts): `ui/src/api/client.ts`

### API services

- [FastAPI application](https://github.com/nathanblatter/finforge/blob/main/api/main.py): `api/main.py`
- [Authentication](https://github.com/nathanblatter/finforge/blob/main/api/auth.py): `api/auth.py`
- [Finance endpoints](https://github.com/nathanblatter/finforge/tree/main/api/routers): `api/routers`
- [Finance calculations](https://github.com/nathanblatter/finforge/tree/main/api/services): `api/services`

### Scheduled data

- [Scheduler](https://github.com/nathanblatter/finforge/blob/main/cron/main.py): `cron/main.py`
- [Plaid sync](https://github.com/nathanblatter/finforge/blob/main/cron/integrations/plaid_sync.py): `cron/integrations/plaid_sync.py`
- [Schwab sync](https://github.com/nathanblatter/finforge/blob/main/cron/integrations/schwab_sync.py): `cron/integrations/schwab_sync.py`
- [Data normalization](https://github.com/nathanblatter/finforge/blob/main/cron/etl/deidentify.py): `cron/etl/deidentify.py`

### Shared finance data

- **PostgreSQL**
- [API data models](https://github.com/nathanblatter/finforge/blob/main/api/models/db_models.py): `api/models/db_models.py`
- [Cron data access](https://github.com/nathanblatter/finforge/blob/main/cron/db.py): `cron/db.py`

### Finance features

- [Spending & budgets](https://github.com/nathanblatter/finforge/blob/main/api/routers/spending.py): `api/routers/spending.py`
- [Portfolio analysis](https://github.com/nathanblatter/finforge/blob/main/ui/src/pages/PortfolioAnalysisPage.tsx): `ui/src/pages/PortfolioAnalysisPage.tsx`
- [AI coach](https://github.com/nathanblatter/finforge/tree/main/api/services/agent): `api/services/agent`
- [Goal tracking](https://github.com/nathanblatter/finforge/blob/main/cron/goal_engine.py): `cron/goal_engine.py`
- [Alerts](https://github.com/nathanblatter/finforge/blob/main/cron/alerts_engine.py): `cron/alerts_engine.py`
- [PDF reports](https://github.com/nathanblatter/finforge/blob/main/api/routers/reports.py): `api/routers/reports.py`
- [Market & options](https://github.com/nathanblatter/finforge/blob/main/api/services/schwab.py): `api/services/schwab.py`
- [iMessage delivery](https://github.com/nathanblatter/finforge/blob/main/cron/imessage_delivery.py): `cron/imessage_delivery.py`

### Other components

- **Finance user**
- **Plaid API**
- **Schwab Trader API**
- **Claude API**

## Connections

- Finance user → React dashboard: uses (evidence: `README.md`)
- React dashboard → API client: requests data
- API client → FastAPI application: calls HTTP API (evidence: `README.md`)
- FastAPI application → Finance endpoints: registers routes (evidence: `api/main.py`)
- Finance endpoints → Authentication: authenticates (evidence: `api/routers/auth.py`)
- Finance endpoints → API data models: queries data (evidence: `api/routers/auth.py`)
- FastAPI application → PostgreSQL: uses PostgreSQL (evidence: `README.md`)
- API data models → PostgreSQL: maps schema
- Scheduler → Plaid sync: runs sync (evidence: `cron/main.py`)
- Scheduler → Schwab sync: runs sync (evidence: `cron/main.py`)
- Plaid sync → Plaid API: fetches accounts (evidence: `README.md`)
- Schwab sync → Schwab Trader API: fetches portfolios (evidence: `README.md`)
- Plaid sync → Data normalization: normalizes records (evidence: `cron/integrations/plaid_sync.py`)
- Schwab sync → Data normalization: normalizes records (evidence: `cron/integrations/schwab_sync.py`)
- Data normalization → Cron data access: persists records (evidence: `cron/integrations/plaid_sync.py`)
- Cron data access → PostgreSQL: reads and writes (evidence: `cron/db.py`)
- Finance endpoints → Spending & budgets: serves spending (evidence: `api/routers/__init__.py`)
- Finance endpoints → Portfolio analysis: serves analysis
- Finance calculations → Market & options: provides market data (evidence: `api/services/quant.py`)
- Scheduler → Goal tracking: runs goal checks (evidence: `cron/main.py`)
- Scheduler → Alerts: runs alert checks (evidence: `cron/main.py`)
- Scheduler → PDF reports: schedules reports
- Scheduler → AI coach: generates insights (evidence: `cron/main.py`)
- AI coach → Claude API: requests completions
- Alerts → iMessage delivery: queues messages
