# codereverser/folioman architecture

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

- Interactive diagram: https://gitdiagram.com/codereverser/folioman
- Repository: https://github.com/codereverser/folioman

## Overview

1. **Overall shape**
   Folioman is a local-first portfolio and tax system with three user-facing runtimes:
   - a **Python backend app**,
   - a **Vue frontend SPA**,
   - and a **desktop shell** that embeds the web UI in a native webview.
   
   The same backend code can also be deployed as a **server app** behind Docker for browser access.

2. **Core domain library**
   The `core/` package is the pure business-logic layer. It contains the domain models and algorithms for:
   - investors, securities, transactions, holdings, NAVs, and quotes,
   - CAS / eCAS parsing,
   - reconciliation and FIFO-based cost basis,
   - tax calculations, including Indian capital-gains rules,
   - valuation and XIRR.
   
   This layer is the main boundary for reusable finance logic and is heavily tested in isolation.

3. **Backend application layer**
   The `app/` package is the Django-style application shell around the domain logic. It provides:
   - database models and migrations,
   - HTTP API endpoints under `app/src/folioman_app/api/`,
   - service orchestration under `services/`,
   - asynchronous/background task entry points under `tasks/`,
   - admin/ops commands under `management/commands/`,
   - settings for desktop vs server modes,
   - WSGI entrypoint and URL routing.
   
   The backend is the system’s central orchestrator: all persistent state, imports, valuation jobs, integrity checks, and exports flow through it.

4. **Data persistence and model boundaries**
   The app persists portfolio state in relational tables defined in `app/src/folioman_app/models/` and migrated through `app/src/folioman_app/migrations/`.
   The core models are split across:
   - **master data**: investors, securities, schemes, families,
   - **ledger data**: transactions, holdings, valuations,
   - **integrity data**: reconciliation and status tracking,
   - **jobs/licensing**: background job state and license metadata.
   
   Settings files indicate support for both **SQLite** and **server-grade DB usage** such as Postgres.

5. **Import pipeline**
   User portfolio data enters through the import APIs and task pipeline:
   - frontend upload or input,
   - backend API endpoints in `api/imports.py`,
   - service layer parsing and normalization,
   - core parsers for **CAS**, **eCAS**, and CSV formats,
   - persistence into transactions/holdings and quarantine/error records.
   
   The architecture separates ingestion from canonical storage so malformed statements can be isolated without corrupting the ledger.

6. **Reconciliation and integrity**
   A distinct subsystem checks whether the stored portfolio is internally consistent:
   - reconciliation logic in `core/reconciliation.py`,
   - integrity models and API endpoints,
   - scheduled or on-demand jobs to recompute status,
   - UI surfaces that show health badges and reconciliation results.
   
   This is not just validation at import time; it is a continuing workflow that compares ledger data, derived holdings, and security status.

7. **Valuation and market/reference data**
   Portfolio valuation is a separate flow from import:
   - NAV refreshes and pricing services live under `services/navs.py`, `services/valuation.py`, and related tasks,
   - reference data comes from external feeds such as **mfapi.in**, **casparser ISIN DB**, **NSE history**, **Yahoo Finance**, and **CoinGecko**,
   - management commands and scheduled jobs refresh quotes and resolve security symbols.
   
   The architecture keeps market data acquisition at the edges so the core valuation logic can operate on stored prices and last-known data even offline.

8. **Jobs and scheduling**
   Background work is modeled explicitly:
   - job state models in `models/jobs.py`,
   - task modules for imports, NAV refresh, ISIN updates, reconciliation, and valuation ticks,
   - a scheduler module plus a `run_scheduler` management command,
   - desktop-specific scheduler installers for Linux, macOS, and Windows.
   
   This makes scheduled valuation and data refresh a first-class subsystem rather than an incidental cron script.

9. **Tax and export subsystem**
   The app includes a tax-oriented output path:
   - capital gains calculations in the core tax modules,
   - export services and API endpoints for report generation,
   - a dedicated worksheet-style UI in the frontend.
   
   This subsystem consumes the canonical transaction and valuation data and produces downstream artifacts for a tax advisor or user review, rather than filing anything externally.

10. **Frontend SPA**
   `frontend/` is a Vue 3 + Vite application that consumes the backend API.
   Its structure is organized by concern:
   - API client and generated schema types,
   - Pinia-like stores for auth, family, investor, integrity, meta, roster, and license state,
   - composables that assemble dashboard and capital-gains views,
   - reusable chart and metric components,
   - route-level views for dashboard, imports, setup, integrity, family, investors, settings, login, and scheme detail.
   
   The SPA is the presentation layer only; it relies on backend state and API contracts, with OpenAPI-generated typing visible in the repo.

11. **Desktop runtime**
   `desktop/` packages Folioman as a native desktop application. It includes:
   - a launcher/bootstrap module,
   - a local server wrapper,
   - a webview API bridge,
   - platform scheduler integration and build scripts.
   
   This runtime is effectively a desktop host around the same backend + frontend stack, optimized for running fully on the user’s machine.

12. **Server/self-hosted runtime**
   `server/` is a lightweight deployment wrapper for running the app as a web service, with Docker-oriented packaging and entrypoint scripts.  
   The README and deployment files show a separate hosted mode intended for family or small-team use behind a reverse proxy.

13. **Security and privacy boundary**
   The project is explicitly local-first:
   - no user accounts or telemetry,
   - sensitive identifiers like PAN are encrypted at rest,
   - network access is limited to public market/reference feeds,
   - auth and licensing are handled inside the app rather than via an external identity service.
   
   This means the main trust boundary is between the user’s device/server and a small set of public data providers.

14. **Cross-cutting build/test/tooling**
   The repo is organized as a monorepo with separate Python packages for `core`, `app`, `desktop`, and `server`, plus a frontend workspace.  
   CI, tests, migrations, and OpenAPI export are used to keep the API contract, domain logic, and UI in sync. This is important architecturally because the frontend is tightly coupled to the backend contract, while the core package stays independently testable.

Main entry points: [`app/src/folioman_app/services`](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/services) (Services), [`core/src/folioman_core/models`](https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/models) (Domain models), [`app/src/folioman_app/api`](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/api) (API layer), [`app/src/folioman_app/tasks`](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/tasks) (Tasks)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_core["Core domain"]
  node_core_models["Domain models<br/>core models"]
  node_core_parsers["CAS parsers<br/>ingestion parsing<br/>[cas_reader.py]"]
  node_core_fifo["FIFO engine<br/>cost-basis engine<br/>[fifo.py]"]
  node_core_recon["Reconciliation<br/>integrity logic<br/>[reconciliation.py]"]
  node_core_tax["Tax engine<br/>tax rules"]
  node_core_valuation["Valuation<br/>pricing logic<br/>[valuation.py]"]
  node_core_feeds["Price feeds<br/>external data adapters"]
end

subgraph group_backend["Backend app"]
  node_app_api["API layer<br/>http api"]
  node_app_services["Services<br/>orchestration"]
  node_app_tasks["Tasks<br/>background jobs"]
  node_app_models[("App models<br/>persistence models")]
  node_app_settings["Settings<br/>runtime config"]
  node_app_scheduler["Scheduler<br/>[scheduler.py]"]
end

subgraph group_ui["Frontend UI"]
  node_frontend_api["API client<br/>typed client"]
  node_frontend_stores["Stores"]
  node_frontend_views["Views"]
  node_frontend_comp["UI components<br/>presentation components"]
end

subgraph group_runtimes["Deployment runtimes"]
  node_desktop_shell["Desktop shell<br/>native host"]
  node_server_pack["Server runtime<br/>deployment wrapper"]
end

subgraph group_ops["Ops and tooling"]
  node_deploy_assets["Deploy assets<br/>deployment config"]
  node_openapi_contract["OpenAPI spec<br/>api contract<br/>[openapi.json]"]
end

node_core_parsers -->|"normalize to"| node_core_models
node_core_models -->|"accounting"| node_core_fifo
node_core_models -->|"verify"| node_core_recon
node_core_models -->|"tax inputs"| node_core_tax
node_core_models -->|"value"| node_core_valuation
node_core_feeds -->|"market data"| node_core_valuation
node_app_api -->|"delegate"| node_app_services
node_app_services -->|"parse imports"| node_core_parsers
node_app_services -->|"reconcile"| node_core_recon
node_app_services -->|"compute"| node_core_valuation
node_app_services -->|"export tax"| node_core_tax
node_app_services -->|"persist"| node_app_models
node_app_tasks -->|"run jobs"| node_app_services
node_app_scheduler -->|"schedule"| node_app_tasks
node_app_settings -->|"configure"| node_app_api
node_frontend_api -->|"typed from"| node_openapi_contract
node_frontend_stores -->|"fetch"| node_frontend_api
node_frontend_views -->|"render state"| node_frontend_stores
node_frontend_comp -->|"compose"| node_frontend_views
node_desktop_shell -->|"runs backend"| node_app_settings
node_desktop_shell -->|"embeds UI"| node_frontend_views
node_server_pack -->|"runs backend"| node_app_settings
node_server_pack -->|"packages with"| node_deploy_assets
node_app_api -.->|"exports"| node_openapi_contract
node_app_models -->|"job state"| node_app_tasks

click node_core_models "https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/models"
click node_core_parsers "https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/cas_reader.py"
click node_core_fifo "https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/fifo.py"
click node_core_recon "https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/reconciliation.py"
click node_core_tax "https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/tax"
click node_core_valuation "https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/valuation.py"
click node_core_feeds "https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/price_feeds"
click node_app_api "https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/api"
click node_app_services "https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/services"
click node_app_tasks "https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/tasks"
click node_app_models "https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/models"
click node_app_settings "https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/settings"
click node_app_scheduler "https://github.com/codereverser/folioman/blob/main/app/src/folioman_app/scheduler.py"
click node_frontend_api "https://github.com/codereverser/folioman/tree/main/frontend/src/api"
click node_frontend_stores "https://github.com/codereverser/folioman/tree/main/frontend/src/stores"
click node_frontend_views "https://github.com/codereverser/folioman/tree/main/frontend/src/views"
click node_frontend_comp "https://github.com/codereverser/folioman/tree/main/frontend/src/components"
click node_desktop_shell "https://github.com/codereverser/folioman/tree/main/desktop/src/folioman_desktop"
click node_server_pack "https://github.com/codereverser/folioman/tree/main/server/src/folioman_server"
click node_deploy_assets "https://github.com/codereverser/folioman/tree/main/deploy"
click node_openapi_contract "https://github.com/codereverser/folioman/blob/main/openapi.json"

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_core_models,node_core_parsers,node_core_fifo,node_core_recon,node_core_tax,node_core_valuation,node_core_feeds toneBlue
class node_app_api,node_app_services,node_app_tasks,node_app_models,node_app_settings,node_app_scheduler toneAmber
class node_frontend_api,node_frontend_stores,node_frontend_views,node_frontend_comp toneMint
class node_desktop_shell,node_server_pack toneRose
class node_deploy_assets,node_openapi_contract toneIndigo
```

## Components

### Core domain

Pure finance logic and models

- [Domain models](https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/models): core models · Investors, securities, transactions, holdings, NAVs, quotes, and related finance entities · `core/src/folioman_core/models`
- [CAS parsers](https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/cas_reader.py): ingestion parsing · CAS, eCAS, and statement parsing plus normalization · `core/src/folioman_core/cas_reader.py`
- [FIFO engine](https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/fifo.py): cost-basis engine · FIFO cost basis and related transaction accounting · `core/src/folioman_core/fifo.py`
- [Reconciliation](https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/reconciliation.py): integrity logic · Ledger consistency checks and derived-state reconciliation · `core/src/folioman_core/reconciliation.py`
- [Tax engine](https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/tax): tax rules · Indian capital-gains policy, schedules, and tax calculations · `core/src/folioman_core/tax`
- [Valuation](https://github.com/codereverser/folioman/blob/main/core/src/folioman_core/valuation.py): pricing logic · Portfolio valuation and XIRR calculations · `core/src/folioman_core/valuation.py`
- [Price feeds](https://github.com/codereverser/folioman/tree/main/core/src/folioman_core/price_feeds): external data adapters · mfapi, NSE history, Yahoo Finance, CoinGecko, and related feeds · `core/src/folioman_core/price_feeds`

### Backend app

Django-style application shell and orchestration

- [API layer](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/api): http api · HTTP endpoints for auth, imports, integrity, jobs, navs, setup, and exports · `app/src/folioman_app/api`
- [Services](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/services): orchestration · Import, NAV, valuation, export, ISIN, and job orchestration · `app/src/folioman_app/services`
- [Tasks](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/tasks): background jobs · Import, reconciliation, NAV refresh, valuation ticks, and ISIN jobs · `app/src/folioman_app/tasks`
- [App models](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/models): persistence models · Relational state for master data, ledger data, integrity, jobs, and licensing · `app/src/folioman_app/models`
- [Settings](https://github.com/codereverser/folioman/tree/main/app/src/folioman_app/settings): runtime config · Desktop and server settings, logging, and SQLite/server mode configuration · `app/src/folioman_app/settings`
- [Scheduler](https://github.com/codereverser/folioman/blob/main/app/src/folioman_app/scheduler.py): job scheduler · Scheduler integration and tick orchestration · `app/src/folioman_app/scheduler.py`

### Frontend UI

Vue SPA presentation layer

- [API client](https://github.com/codereverser/folioman/tree/main/frontend/src/api): typed client · Frontend HTTP client and generated schema types · `frontend/src/api`
- [Stores](https://github.com/codereverser/folioman/tree/main/frontend/src/stores): state stores · Auth, family, investor, integrity, meta, roster, and license state · `frontend/src/stores`
- [Views](https://github.com/codereverser/folioman/tree/main/frontend/src/views): route views · Dashboard, imports, integrity, family, investors, settings, login, setup, and scheme detail screens · `frontend/src/views`
- [UI components](https://github.com/codereverser/folioman/tree/main/frontend/src/components): presentation components · Reusable cards, badges, charts, and dashboard widgets · `frontend/src/components`

### Deployment runtimes

Desktop and server packaging around the same app

- [Desktop shell](https://github.com/codereverser/folioman/tree/main/desktop/src/folioman_desktop): native host · Bootstrap, webview bridge, local server wrapper, and desktop scheduler integration · `desktop/src/folioman_desktop`
- [Server runtime](https://github.com/codereverser/folioman/tree/main/server/src/folioman_server): deployment wrapper · Docker-oriented server packaging and entrypoint for hosted use · `server/src/folioman_server`

### Ops and tooling

Build, deploy, and contract artifacts

- [Deploy assets](https://github.com/codereverser/folioman/tree/main/deploy): deployment config · Hosted compose files, Dockerfile, and environment examples · `deploy`
- [OpenAPI spec](https://github.com/codereverser/folioman/blob/main/openapi.json): api contract · Generated API contract used to keep backend and SPA aligned · `openapi.json`

## Connections

- CAS parsers → Domain models: normalize to · Statement parsing produces canonical domain objects
- Domain models → FIFO engine: accounting · Transactions and holdings feed FIFO cost basis
- Domain models → Reconciliation: verify · Stored ledger state is checked against derived consistency
- Domain models → Tax engine: tax inputs · Canonical transactions and holdings feed capital-gains logic
- Domain models → Valuation: value · Portfolio entities are priced and aggregated
- Price feeds → Valuation: market data · External prices feed valuation computations
- API layer → Services: delegate · Endpoints hand work to orchestration services
- Services → CAS parsers: parse imports · Import services invoke CAS/eCAS normalization
- Services → Reconciliation: reconcile · Service layer triggers integrity workflows
- Services → Valuation: compute · Valuation services use core pricing logic
- Services → Tax engine: export tax · Tax export services consume core tax calculations
- Services → App models: persist · Services write canonical and derived state to relational tables
- Tasks → Services: run jobs · Background tasks execute service workflows
- Scheduler → Tasks: schedule · Scheduler dispatches periodic and on-demand tasks
- Settings → API layer: configure · Runtime settings select backend mode and API behavior
- API client → OpenAPI spec: typed from · Generated client and schema types track the backend contract
- Stores → API client: fetch · State stores coordinate API access
- Views → Stores: render state · Route views consume store state and actions
- UI components → Views: compose · Reusable UI pieces are assembled into screens
- Desktop shell → Settings: runs backend · Desktop host launches the local backend in desktop mode
- Desktop shell → Views: embeds UI · Webview bridge presents the SPA inside the native shell
- Server runtime → Settings: runs backend · Hosted runtime uses server mode settings
- Server runtime → Deploy assets: packages with · Server wrapper is deployed through Docker assets
- API layer → OpenAPI spec: exports · API surface is published as an OpenAPI spec
- App models → Tasks: job state · Job and licensing models track asynchronous work
