How codereverser/folioman works
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: services Services · models Domain models · api API layer · tasks Tasks
Components 21
Core domain
Pure finance logic and models
- Domain models · Investors, securities, transactions, holdings, NAVs, quotes, and related finance entities
core/src/folioman_core/models - CAS parsers · CAS, eCAS, and statement parsing plus normalization
core/src/folioman_core/cas_reader.py - FIFO engine · FIFO cost basis and related transaction accounting
core/src/folioman_core/fifo.py - Reconciliation · Ledger consistency checks and derived-state reconciliation
core/src/folioman_core/reconciliation.py - Tax engine · Indian capital-gains policy, schedules, and tax calculations
core/src/folioman_core/tax - Valuation · Portfolio valuation and XIRR calculations
core/src/folioman_core/valuation.py - Price feeds · 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 · HTTP endpoints for auth, imports, integrity, jobs, navs, setup, and exports
app/src/folioman_app/api - Services · Import, NAV, valuation, export, ISIN, and job orchestration
app/src/folioman_app/services - Tasks · Import, reconciliation, NAV refresh, valuation ticks, and ISIN jobs
app/src/folioman_app/tasks - App models · Relational state for master data, ledger data, integrity, jobs, and licensing
app/src/folioman_app/models - Settings · Desktop and server settings, logging, and SQLite/server mode configuration
app/src/folioman_app/settings - Scheduler · Scheduler integration and tick orchestration
app/src/folioman_app/scheduler.py
Frontend UI
Vue SPA presentation layer
- API client · Frontend HTTP client and generated schema types
frontend/src/api - Stores · Auth, family, investor, integrity, meta, roster, and license state
frontend/src/stores - Views · Dashboard, imports, integrity, family, investors, settings, login, setup, and scheme detail screens
frontend/src/views - UI components · Reusable cards, badges, charts, and dashboard widgets
frontend/src/components
Deployment runtimes
Desktop and server packaging around the same app
- Desktop shell · Bootstrap, webview bridge, local server wrapper, and desktop scheduler integration
desktop/src/folioman_desktop - Server runtime · Docker-oriented server packaging and entrypoint for hosted use
server/src/folioman_server
Ops and tooling
Build, deploy, and contract artifacts
- Deploy assets · Hosted compose files, Dockerfile, and environment examples
deploy - OpenAPI spec · Generated API contract used to keep backend and SPA aligned
openapi.json
Connections 25
- 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