# marketcalls/opencase architecture

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

- Interactive diagram: https://gitdiagram.com/marketcalls/opencase
- Repository: https://github.com/marketcalls/opencase

## Overview

#### 1. Purpose and Runtime
OpenCase is a self-hosted stock-basket platform: users authenticate, connect Zerodha or Angel One accounts, build weighted baskets, place/rebalance investments, and inspect broker/OpenCase holdings. It runs as a TypeScript Hono application targeted at Cloudflare Pages/Workers, with a Vite-built vanilla-JS UI.
- `src/index.tsx`
- `src/renderer.tsx`
- `wrangler.jsonc`

#### 2. Application Entry and HTTP Composition
`src/index.tsx` is the main application entry: it serves HTML/UI routes and mounts the domain API handlers. Route modules form the backend boundary for setup, identity, broker accounts, baskets, instruments, investments, portfolio, SIPs, and alerts. The browser client consumes these APIs rather than using a separate SPA backend.
- `src/index.tsx`
- `src/routes/baskets.ts`
- `public/static/app.js`

#### 3. Identity, Sessions, and Platform Setup
User signup/login/profile handling is separated from legacy broker-oriented auth. The first user may become admin; sessions are stored in Cloudflare KV. Setup endpoints manage platform-level broker configuration/default selection, while broker-account endpoints manage per-user linked accounts and encrypted credentials.
- `src/routes/user.ts`
- `src/routes/setup.ts`
- `src/routes/broker-accounts.ts`

#### 4. Broker Abstraction and External Execution Boundary
A broker factory selects a common broker interface for Zerodha and Angel One. Adapter implementations normalize authentication, holdings, market data, and order-facing behavior despite different OAuth/TOTP and API protocols. This is the principal boundary between OpenCase’s unified domain model and external broker services.
- `src/brokers/base.ts`
- `src/brokers/factory.ts`
- `src/brokers/zerodha.ts`
- `src/brokers/angelone.ts`

#### 5. Instrument Master and Market Data Flow
Instrument routes download broker catalogs, merge them into unified symbols while retaining broker-specific tokens, and support stock/index search and LTP lookup. Broker API clients provide the vendor-specific transport layer. Unified instruments enable basket composition, benchmarks, and portable holdings mapping.
- `src/routes/instruments.ts`
- `src/lib/kite.ts`
- `src/lib/angelone.ts`
- `migrations/0002_master_instruments.sql`
- `migrations/0003_unified_symbols.sql`

#### 6. Basket-to-Investment and Portfolio Flow
Users define baskets with constituent weights; investment operations translate a basket into broker order actions through the active connected account. Portfolio routes aggregate persisted OpenCase investments with normalized live broker holdings for P&L, comparison, and rebalancing. SIPs and alerts are adjacent lifecycle workflows; scheduled execution is isolated from request handling.
- `src/routes/baskets.ts`
- `src/routes/investments.ts`
- `src/routes/portfolio.ts`
- `src/scheduled.ts`

#### 7. Persistence and Deployment Boundaries
Cloudflare D1 (SQLite) persists users, broker links, instruments, baskets, investments, and related records; migrations establish the evolving schema and seed data supplies templates. Cloudflare KV holds sessions. Docker Compose provides a local/container deployment path, while Wrangler configures production Cloudflare bindings.
- `migrations/0001_initial_schema.sql`
- `migrations/0004_user_auth.sql`
- `migrations/0005_investment_broker_link.sql`
- `docker-compose.yml`
- `wrangler.jsonc`

Main entry points: [`src/index.tsx`](https://github.com/marketcalls/opencase/blob/main/src/index.tsx) (Hono app entry), [`migrations/0001_initial_schema.sql`](https://github.com/marketcalls/opencase/blob/main/migrations/0001_initial_schema.sql) (Cloudflare D1), [`src/brokers/factory.ts`](https://github.com/marketcalls/opencase/blob/main/src/brokers/factory.ts) (Broker factory), [`src/routes/user.ts`](https://github.com/marketcalls/opencase/blob/main/src/routes/user.ts) (User & session APIs)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Browser UI"]
  node_ui["Vanilla JS UI<br/>browser client<br/>[app.js]"]
end

subgraph group_worker["Cloudflare Application"]
  node_app{{"Hono app entry<br/>Worker application<br/>[index.tsx]"}}
  node_renderer["HTML renderer<br/>server renderer<br/>[renderer.tsx]"]
  node_user_routes["User &amp; session APIs<br/>route module<br/>[user.ts]"]
  node_setup_routes["Platform setup APIs<br/>route module<br/>[setup.ts]"]
  node_account_routes["Broker account APIs<br/>route module<br/>[broker-accounts.ts]"]
  node_basket_routes["Basket APIs<br/>route module<br/>[baskets.ts]"]
  node_investment_routes["Investment APIs<br/>route module<br/>[investments.ts]"]
  node_portfolio_routes["Portfolio APIs<br/>route module<br/>[portfolio.ts]"]
  node_instrument_routes["Instrument APIs<br/>route module<br/>[instruments.ts]"]
  node_scheduled["Scheduled lifecycle jobs<br/>scheduled Worker<br/>[scheduled.ts]"]
end

subgraph group_brokers["Broker Integration"]
  node_broker_factory{{"Broker factory<br/>broker abstraction<br/>[factory.ts]"}}
  node_broker_interface["Common broker interface<br/>broker contract<br/>[base.ts]"]
  node_zerodha["Zerodha adapter<br/>broker adapter<br/>[zerodha.ts]"]
  node_angelone["Angel One adapter<br/>broker adapter<br/>[angelone.ts]"]
  node_broker_clients["Broker API clients<br/>vendor transport<br/>[kite.ts]"]
end

subgraph group_storage["Persistence &amp; Deployment"]
  node_d1[("Cloudflare D1<br/>SQLite database")]
  node_kv[("Cloudflare KV<br/>session store")]
  node_wrangler["Cloudflare bindings<br/>deployment config<br/>[wrangler.jsonc]"]
end

node_ui -->|"HTTP routes"| node_app
node_app -->|"renders HTML"| node_renderer
node_app -->|"mounts"| node_user_routes
node_app -->|"mounts"| node_setup_routes
node_app -->|"mounts"| node_account_routes
node_app -->|"mounts"| node_basket_routes
node_app -->|"mounts"| node_investment_routes
node_app -->|"mounts"| node_portfolio_routes
node_app -->|"mounts"| node_instrument_routes
node_user_routes -->|"stores sessions"| node_kv
node_user_routes -->|"persists users"| node_d1
node_setup_routes -->|"persists configuration"| node_d1
node_account_routes -->|"persists broker links"| node_d1
node_basket_routes -->|"persists baskets"| node_d1
node_investment_routes -->|"executes through"| node_broker_factory
node_investment_routes -->|"persists investments"| node_d1
node_portfolio_routes -->|"reads investments"| node_d1
node_portfolio_routes -->|"fetches live holdings"| node_broker_factory
node_instrument_routes -->|"downloads catalogs and LTP"| node_broker_clients
node_instrument_routes -->|"merges unified instruments"| node_d1
node_broker_factory -->|"returns contract"| node_broker_interface
node_broker_interface -->|"implemented by"| node_zerodha
node_broker_interface -->|"implemented by"| node_angelone
node_scheduled -->|"processes lifecycle data"| node_d1
node_scheduled -->|"executes scheduled actions"| node_broker_factory
node_wrangler -.->|"deploys and binds"| node_app

click node_ui "https://github.com/marketcalls/opencase/blob/main/public/static/app.js"
click node_app "https://github.com/marketcalls/opencase/blob/main/src/index.tsx"
click node_renderer "https://github.com/marketcalls/opencase/blob/main/src/renderer.tsx"
click node_user_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/user.ts"
click node_setup_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/setup.ts"
click node_account_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/broker-accounts.ts"
click node_basket_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/baskets.ts"
click node_investment_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/investments.ts"
click node_portfolio_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/portfolio.ts"
click node_instrument_routes "https://github.com/marketcalls/opencase/blob/main/src/routes/instruments.ts"
click node_scheduled "https://github.com/marketcalls/opencase/blob/main/src/scheduled.ts"
click node_broker_factory "https://github.com/marketcalls/opencase/blob/main/src/brokers/factory.ts"
click node_broker_interface "https://github.com/marketcalls/opencase/blob/main/src/brokers/base.ts"
click node_zerodha "https://github.com/marketcalls/opencase/blob/main/src/brokers/zerodha.ts"
click node_angelone "https://github.com/marketcalls/opencase/blob/main/src/brokers/angelone.ts"
click node_broker_clients "https://github.com/marketcalls/opencase/blob/main/src/lib/kite.ts"
click node_d1 "https://github.com/marketcalls/opencase/blob/main/migrations/0001_initial_schema.sql"
click node_wrangler "https://github.com/marketcalls/opencase/blob/main/wrangler.jsonc"

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 toneBlue
class node_app,node_renderer,node_user_routes,node_setup_routes,node_account_routes,node_basket_routes,node_investment_routes,node_portfolio_routes,node_instrument_routes,node_scheduled toneAmber
class node_broker_factory,node_broker_interface,node_zerodha,node_angelone,node_broker_clients toneMint
class node_d1,node_kv,node_wrangler toneRose
```

## Components

### Browser UI

- [Vanilla JS UI](https://github.com/marketcalls/opencase/blob/main/public/static/app.js): browser client · Consumes the application APIs. · `public/static/app.js`

### Cloudflare Application

- [Hono app entry](https://github.com/marketcalls/opencase/blob/main/src/index.tsx): Worker application · Serves UI routes and mounts domain APIs. · `src/index.tsx`
- [HTML renderer](https://github.com/marketcalls/opencase/blob/main/src/renderer.tsx): server renderer · `src/renderer.tsx`
- [User & session APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/user.ts): route module · Handles signup, login, profiles, and initial admin assignment. · `src/routes/user.ts`
- [Platform setup APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/setup.ts): route module · Manages broker configuration and defaults. · `src/routes/setup.ts`
- [Broker account APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/broker-accounts.ts): route module · Manages per-user broker links and encrypted credentials. · `src/routes/broker-accounts.ts`
- [Basket APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/baskets.ts): route module · Defines weighted basket constituents. · `src/routes/baskets.ts`
- [Investment APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/investments.ts): route module · Turns basket operations into broker order actions. · `src/routes/investments.ts`
- [Portfolio APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/portfolio.ts): route module · Combines persisted investments with live normalized holdings. · `src/routes/portfolio.ts`
- [Instrument APIs](https://github.com/marketcalls/opencase/blob/main/src/routes/instruments.ts): route module · Imports catalogs, resolves unified symbols, searches, and fetches LTP. · `src/routes/instruments.ts`
- [Scheduled lifecycle jobs](https://github.com/marketcalls/opencase/blob/main/src/scheduled.ts): scheduled Worker · Runs SIP and alert workflows outside requests. · `src/scheduled.ts`

### Broker Integration

- [Broker factory](https://github.com/marketcalls/opencase/blob/main/src/brokers/factory.ts): broker abstraction · Selects the common interface for the active linked broker. · `src/brokers/factory.ts`
- [Common broker interface](https://github.com/marketcalls/opencase/blob/main/src/brokers/base.ts): broker contract · Normalizes authentication, holdings, market data, and orders. · `src/brokers/base.ts`
- [Zerodha adapter](https://github.com/marketcalls/opencase/blob/main/src/brokers/zerodha.ts): broker adapter · `src/brokers/zerodha.ts`
- [Angel One adapter](https://github.com/marketcalls/opencase/blob/main/src/brokers/angelone.ts): broker adapter · `src/brokers/angelone.ts`
- [Broker API clients](https://github.com/marketcalls/opencase/blob/main/src/lib/kite.ts): vendor transport · Implements vendor-specific catalog and market-data transport. · `src/lib/kite.ts`

### Persistence & Deployment

- [Cloudflare D1](https://github.com/marketcalls/opencase/blob/main/migrations/0001_initial_schema.sql): SQLite database · Stores users, links, instruments, baskets, investments, and records. · `migrations/0001_initial_schema.sql`
- **Cloudflare KV**: session store
- [Cloudflare bindings](https://github.com/marketcalls/opencase/blob/main/wrangler.jsonc): deployment config · Configures production Worker and D1/KV bindings. · `wrangler.jsonc`

## Connections

- Vanilla JS UI → Hono app entry: HTTP routes
- Hono app entry → HTML renderer: renders HTML
- Hono app entry → User & session APIs: mounts
- Hono app entry → Platform setup APIs: mounts
- Hono app entry → Broker account APIs: mounts
- Hono app entry → Basket APIs: mounts
- Hono app entry → Investment APIs: mounts
- Hono app entry → Portfolio APIs: mounts
- Hono app entry → Instrument APIs: mounts
- User & session APIs → Cloudflare KV: stores sessions
- User & session APIs → Cloudflare D1: persists users
- Platform setup APIs → Cloudflare D1: persists configuration
- Broker account APIs → Cloudflare D1: persists broker links
- Basket APIs → Cloudflare D1: persists baskets
- Investment APIs → Broker factory: executes through
- Investment APIs → Cloudflare D1: persists investments
- Portfolio APIs → Cloudflare D1: reads investments
- Portfolio APIs → Broker factory: fetches live holdings
- Instrument APIs → Broker API clients: downloads catalogs and LTP
- Instrument APIs → Cloudflare D1: merges unified instruments
- Broker factory → Common broker interface: returns contract
- Common broker interface → Zerodha adapter: implemented by
- Common broker interface → Angel One adapter: implemented by
- Scheduled lifecycle jobs → Cloudflare D1: processes lifecycle data
- Scheduled lifecycle jobs → Broker factory: executes scheduled actions
- Cloudflare bindings → Hono app entry: deploys and binds
