# oskar-norborg/nordlys architecture

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

- Interactive diagram: https://gitdiagram.com/oskar-norborg/nordlys
- Repository: https://github.com/oskar-norborg/nordlys

## Overview

NORDLYS is a browser-based private-wealth planning app: users can model a household plan, build a portfolio from locally imported transactions, assess risk on that portfolio, and run strategy backtests. The graph preserves these distinct workflows plus options and PDF reporting. The README documents the product capabilities; sampled source confirms key persistence, import, simulation, and backtest behavior, but does not expose every screen-to-engine call, so uncertain wiring is omitted.

Main entry points: [`src/engine/backtest/client.ts`](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/client.ts) (Backtest client), [`src/components/portfolio/portfolio-page.tsx`](https://github.com/oskar-norborg/nordlys/blob/main/src/components/portfolio/portfolio-page.tsx) (Portfolio view), [`src/store/app-store.ts`](https://github.com/oskar-norborg/nordlys/blob/main/src/store/app-store.ts) (App state), [`src/router.tsx`](https://github.com/oskar-norborg/nordlys/blob/main/src/router.tsx) (App router)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["App experience"]
  node_router["App router<br/>[router.tsx]"]
  node_shell["App shell<br/>[app-shell.tsx]"]
  node_state["App state<br/>[app-store.ts]"]
  node_browserdata[("Browser storage<br/>[storage.ts]")]
end

subgraph group_portfolio["Portfolio workflow"]
  node_importui["Transaction import<br/>[import-page.tsx]"]
  node_ledger["Ledger import pipeline<br/>[pipeline.ts]"]
  node_portfolio["Portfolio view<br/>[portfolio-page.tsx]"]
  node_holdings["Holdings analytics<br/>[holdings.ts]"]
  node_gap["Portfolio gap analysis<br/>[gap.ts]"]
end

subgraph group_planning["Planning and risk"]
  node_planner["Household planner<br/>[planner-page.tsx]"]
  node_simulation["Monte Carlo client<br/>[mc-client.ts]"]
  node_simengine["Monte Carlo engine<br/>[montecarlo.ts]"]
  node_risk["Risk assessment<br/>[risk-page.tsx]"]
  node_riskengine["Risk calculations<br/>[risk.ts]"]
  node_options["Options analysis<br/>[options-page.tsx]"]
end

subgraph group_research["Strategy research"]
  node_backtest["Backtest workspace<br/>[backtest-page.tsx]"]
  node_strategy["Strategy language<br/>[compile.ts]"]
  node_backtestclient["Backtest client<br/>[client.ts]"]
  node_backtestengine["Backtest engine<br/>[engine.ts]"]
  node_sweep["Sweep and validation<br/>[sweep.ts]"]
  node_diagnostics["Engine diagnostics<br/>[diagnostics.tsx]"]
end

subgraph group_reporting["Reporting"]
  node_pdf["PDF reporting<br/>[index.ts]"]
end

node_user(("Household user"))

node_user -->|"opens screens"| node_router
node_router -->|"renders routes"| node_shell
node_shell -->|"reads and updates"| node_state
node_state -->|"persists locally"| node_browserdata
node_user -->|"selects export"| node_importui
node_importui -->|"imports rows"| node_ledger
node_ledger -->|"updates ledger"| node_state
node_user -->|"reviews holdings"| node_portfolio
node_portfolio -->|"analyzes ledger"| node_holdings
node_portfolio -->|"checks allocation gaps"| node_gap
node_user -->|"enters household goals"| node_planner
node_planner -->|"requests simulation"| node_simulation
node_simulation -->|"runs locally or in worker"| node_simengine
node_user -->|"reviews portfolio risk"| node_risk
node_risk -->|"calculates risk"| node_riskengine
node_user -->|"explores options"| node_options
node_user -->|"defines strategy"| node_backtest
node_backtest -->|"submits jobs"| node_backtestclient
node_backtestclient -->|"compiles source"| node_strategy
node_backtestclient -->|"runs backtest"| node_backtestengine
node_backtestclient -->|"runs parameter sweep"| node_sweep
node_user -->|"opens diagnostics"| node_diagnostics
node_user -->|"requests report"| node_pdf

click node_router "https://github.com/oskar-norborg/nordlys/blob/main/src/router.tsx"
click node_shell "https://github.com/oskar-norborg/nordlys/blob/main/src/components/shell/app-shell.tsx"
click node_state "https://github.com/oskar-norborg/nordlys/blob/main/src/store/app-store.ts"
click node_browserdata "https://github.com/oskar-norborg/nordlys/blob/main/src/data/storage.ts"
click node_importui "https://github.com/oskar-norborg/nordlys/blob/main/src/components/import/import-page.tsx"
click node_ledger "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/ledger/pipeline.ts"
click node_portfolio "https://github.com/oskar-norborg/nordlys/blob/main/src/components/portfolio/portfolio-page.tsx"
click node_holdings "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/ledger/holdings.ts"
click node_gap "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/ledger/gap.ts"
click node_planner "https://github.com/oskar-norborg/nordlys/blob/main/src/components/planner/planner-page.tsx"
click node_simulation "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/mc-client.ts"
click node_simengine "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/montecarlo.ts"
click node_risk "https://github.com/oskar-norborg/nordlys/blob/main/src/components/risk/risk-page.tsx"
click node_riskengine "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/risk.ts"
click node_options "https://github.com/oskar-norborg/nordlys/blob/main/src/components/options/options-page.tsx"
click node_backtest "https://github.com/oskar-norborg/nordlys/blob/main/src/components/backtest/backtest-page.tsx"
click node_strategy "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/strategy/compile.ts"
click node_backtestclient "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/client.ts"
click node_backtestengine "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/engine.ts"
click node_sweep "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/sweep.ts"
click node_diagnostics "https://github.com/oskar-norborg/nordlys/blob/main/src/routes/diagnostics.tsx"
click node_pdf "https://github.com/oskar-norborg/nordlys/blob/main/src/engine/pdf/index.ts"

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_router,node_shell,node_state,node_browserdata,node_user toneBlue
class node_importui,node_ledger,node_portfolio,node_holdings,node_gap toneAmber
class node_planner,node_simulation,node_simengine,node_risk,node_riskengine,node_options toneMint
class node_backtest,node_strategy,node_backtestclient,node_backtestengine,node_sweep,node_diagnostics toneRose
class node_pdf toneIndigo
```

## Components

### App experience

- [App router](https://github.com/oskar-norborg/nordlys/blob/main/src/router.tsx): `src/router.tsx`
- [App shell](https://github.com/oskar-norborg/nordlys/blob/main/src/components/shell/app-shell.tsx): `src/components/shell/app-shell.tsx`
- [App state](https://github.com/oskar-norborg/nordlys/blob/main/src/store/app-store.ts): `src/store/app-store.ts`
- [Browser storage](https://github.com/oskar-norborg/nordlys/blob/main/src/data/storage.ts): `src/data/storage.ts`

### Portfolio workflow

- [Transaction import](https://github.com/oskar-norborg/nordlys/blob/main/src/components/import/import-page.tsx): `src/components/import/import-page.tsx`
- [Ledger import pipeline](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/ledger/pipeline.ts): `src/engine/ledger/pipeline.ts`
- [Portfolio view](https://github.com/oskar-norborg/nordlys/blob/main/src/components/portfolio/portfolio-page.tsx): `src/components/portfolio/portfolio-page.tsx`
- [Holdings analytics](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/ledger/holdings.ts): `src/engine/ledger/holdings.ts`
- [Portfolio gap analysis](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/ledger/gap.ts): `src/engine/ledger/gap.ts`

### Planning and risk

- [Household planner](https://github.com/oskar-norborg/nordlys/blob/main/src/components/planner/planner-page.tsx): `src/components/planner/planner-page.tsx`
- [Monte Carlo client](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/mc-client.ts): `src/engine/mc-client.ts`
- [Monte Carlo engine](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/montecarlo.ts): `src/engine/montecarlo.ts`
- [Risk assessment](https://github.com/oskar-norborg/nordlys/blob/main/src/components/risk/risk-page.tsx): `src/components/risk/risk-page.tsx`
- [Risk calculations](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/risk.ts): `src/engine/risk.ts`
- [Options analysis](https://github.com/oskar-norborg/nordlys/blob/main/src/components/options/options-page.tsx): `src/components/options/options-page.tsx`

### Strategy research

- [Backtest workspace](https://github.com/oskar-norborg/nordlys/blob/main/src/components/backtest/backtest-page.tsx): `src/components/backtest/backtest-page.tsx`
- [Strategy language](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/strategy/compile.ts): `src/engine/strategy/compile.ts`
- [Backtest client](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/client.ts): `src/engine/backtest/client.ts`
- [Backtest engine](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/engine.ts): `src/engine/backtest/engine.ts`
- [Sweep and validation](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/backtest/sweep.ts): `src/engine/backtest/sweep.ts`
- [Engine diagnostics](https://github.com/oskar-norborg/nordlys/blob/main/src/routes/diagnostics.tsx): `src/routes/diagnostics.tsx`

### Reporting

- [PDF reporting](https://github.com/oskar-norborg/nordlys/blob/main/src/engine/pdf/index.ts): `src/engine/pdf/index.ts`

### Other components

- **Household user**

## Connections

- Household user → App router: opens screens
- App router → App shell: renders routes
- App shell → App state: reads and updates
- App state → Browser storage: persists locally
- Household user → Transaction import: selects export
- Transaction import → Ledger import pipeline: imports rows
- Ledger import pipeline → App state: updates ledger
- Household user → Portfolio view: reviews holdings
- Portfolio view → Holdings analytics: analyzes ledger
- Portfolio view → Portfolio gap analysis: checks allocation gaps
- Household user → Household planner: enters household goals
- Household planner → Monte Carlo client: requests simulation
- Monte Carlo client → Monte Carlo engine: runs locally or in worker
- Household user → Risk assessment: reviews portfolio risk
- Risk assessment → Risk calculations: calculates risk
- Household user → Options analysis: explores options
- Household user → Backtest workspace: defines strategy
- Backtest workspace → Backtest client: submits jobs
- Backtest client → Strategy language: compiles source
- Backtest client → Backtest engine: runs backtest
- Backtest client → Sweep and validation: runs parameter sweep
- Household user → Engine diagnostics: opens diagnostics
- Household user → PDF reporting: requests report
