# smyanverma/tradeledger architecture

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

- Interactive diagram: https://gitdiagram.com/smyanverma/tradeledger
- Repository: https://github.com/smyanverma/tradeledger

## Overview

#### Purpose and Runtime Entry Points
TradeLedger is a Django REST API for wallet funding and user-to-user money transfer. Its core guarantee is an immutable double-entry ledger, backed by derived wallet balances, idempotent requests, and database-level concurrency control.

HTTP starts through `tradeledger/manage.py`, Django routing in `tradeledger/config/urls.py`, and ASGI/WSGI deployment entry points in `tradeledger/config/asgi.py` and `tradeledger/config/wsgi.py`. Celery workers load the app from `tradeledger/config/celery.py`.

#### API Composition and Authentication
The project is organized as three Django apps: accounts, wallets, and ledger. Global URL routing delegates public API surfaces to app-specific routes:
- `tradeledger/config/urls.py`
- `tradeledger/apps/accounts/urls.py`
- `tradeledger/apps/wallets/urls.py`
- `tradeledger/apps/ledger/urls.py`

Accounts owns the custom user model and registration/login/profile APIs. JWT access and refresh tokens form the authentication boundary for wallet and ledger operations:
- `tradeledger/apps/accounts/models.py`
- `tradeledger/apps/accounts/views.py`
- `tradeledger/apps/accounts/serializers.py`

Registration creates a user and an initially empty wallet, linking identity provisioning to the wallet domain.

#### Wallet Domain and Funding Boundary
Wallets represent each user’s available balance. The balance is a cached/derived operational value rather than the authoritative financial record. Wallet APIs expose the caller’s wallet and a top-up endpoint; top-up is explicitly a demo/payment-gateway simulation boundary, not an external payment integration:
- `tradeledger/apps/wallets/models.py`
- `tradeledger/apps/wallets/views.py`
- `tradeledger/apps/wallets/serializers.py`

The wallet layer supplies the mutable balances that the transfer service updates atomically, while ledger entries provide auditability and source-of-truth history.

#### Ledger and Transfer Orchestration
The ledger app contains transactions, immutable debit/credit ledger entries, transfer APIs, statements, and the central money-movement service:
- `tradeledger/apps/ledger/models.py`
- `tradeledger/apps/ledger/services.py`
- `tradeledger/apps/ledger/views.py`

A transfer request identifies a receiving user, amount, narration, and client idempotency key. The service is the critical control boundary: it validates the operation, creates/reuses the transaction according to its database-enforced unique idempotency constraint, and records exactly two ledger entries—a sender DEBIT and receiver CREDIT—which net to zero.

#### Transaction Safety and Consistency
Transfer execution relies on PostgreSQL transactions and row locks. Sender and receiver wallets are selected with `SELECT … FOR UPDATE` in a stable order before balance reads or writes. This serializes competing debits, prevents overdrafts under races, and avoids lock-order deadlocks.

The database, migrations, and model constraints—not request-level caching or preflight checks—are the consistency authority:
- `tradeledger/apps/ledger/migrations/0001_initial.py`
- `tradeledger/apps/wallets/migrations/0001_initial.py`
- `tradeledger/apps/accounts/migrations/0001_initial.py`

Transaction-history and statement endpoints read the transaction and raw ledger-entry views separately, preserving the distinction between transfer-level records and accounting rows.

#### Asynchronous Notifications
After a completed transaction, notification work is dispatched outside the synchronous API response path through Celery:
- `tradeledger/apps/ledger/tasks.py`
- `tradeledger/config/celery.py`
- `tradeledger/apps/ledger/services.py`

This separates irreversible financial persistence from potentially slow notification delivery. Redis is the Celery broker/result backend and is also configured for Django caching.

#### Infrastructure and External Dependencies
Django 5 and Django REST Framework provide the API runtime; PostgreSQL provides locking, transactions, and durable constraints; Redis supports Celery and caching; SimpleJWT provides auth; drf-spectacular publishes OpenAPI/Swagger documentation. Docker Compose runs the web process, PostgreSQL, Redis, and Celery worker:
- `tradeledger/docker-compose.yml`
- `tradeledger/Dockerfile`
- `tradeledger/config/settings.py`

Main entry points: [`tradeledger/apps/ledger/services.py`](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/services.py) (Transfer service), [`tradeledger/docker-compose.yml`](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/docker-compose.yml) (Docker Compose), [`tradeledger/config/urls.py`](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/urls.py) (Global URL routing), [`tradeledger/apps/ledger/views.py`](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/views.py) (Transfer & statement API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["API &amp; Identity"]
  node_django_entry{{"Django entry points<br/>runtime entry<br/>[manage.py]"}}
  node_root_urls["Global URL routing<br/>Django routing<br/>[urls.py]"]
  node_account_api["Accounts API<br/>Django app<br/>[views.py]"]
  node_user_model["Custom user<br/>identity model<br/>[models.py]"]
  node_jwt["JWT authentication<br/>auth boundary<br/>[serializers.py]"]
end

subgraph group_finance["Wallet &amp; Ledger"]
  node_wallet_api["Wallet API<br/>Django app<br/>[views.py]"]
  node_wallets["Wallet balances<br/>derived balance model<br/>[models.py]"]
  node_ledger_api["Transfer &amp; statement API<br/>Django app<br/>[views.py]"]
  node_transfer_service{{"Transfer service<br/>money movement service<br/>[services.py]"}}
  node_ledger_models["Transactions &amp; entries<br/>immutable ledger models<br/>[models.py]"]
  node_db_constraints["Schema constraints<br/>Django migrations<br/>[0001_initial.py]"]
end

subgraph group_async["Async Delivery"]
  node_celery_config["Celery runtime<br/>worker configuration<br/>[celery.py]"]
  node_notification_task["Transaction notifications<br/>Celery task<br/>[tasks.py]"]
end

subgraph group_infra["Runtime Infrastructure"]
  node_postgres[("PostgreSQL<br/>primary database")]
  node_redis["Redis<br/>broker, backend &amp; cache"]
  node_settings["Application settings<br/>Django configuration<br/>[settings.py]"]
  node_compose["Docker Compose<br/>deployment composition<br/>[docker-compose.yml]"]
end

node_django_entry -->|"serves"| node_root_urls
node_root_urls -->|"routes to"| node_account_api
node_root_urls -->|"routes to"| node_wallet_api
node_root_urls -->|"routes to"| node_ledger_api
node_account_api -->|"creates and reads"| node_user_model
node_account_api -->|"provisions empty wallet"| node_wallets
node_jwt -->|"authorizes"| node_wallet_api
node_jwt -->|"authorizes"| node_ledger_api
node_wallet_api -->|"reads and tops up"| node_wallets
node_ledger_api -->|"submits transfers"| node_transfer_service
node_ledger_api -->|"reads statements"| node_ledger_models
node_transfer_service -->|"locks and updates"| node_wallets
node_transfer_service -->|"creates paired entries"| node_ledger_models
node_transfer_service -->|"relies on idempotency"| node_db_constraints
node_wallets -->|"persists in"| node_postgres
node_ledger_models -->|"persists in"| node_postgres
node_db_constraints -->|"enforced by"| node_postgres
node_transfer_service -.->|"dispatches after completion"| node_notification_task
node_celery_config -->|"loads"| node_notification_task
node_notification_task -->|"uses broker/backend"| node_redis
node_settings -.->|"configures"| node_postgres
node_settings -.->|"configures cache"| node_redis
node_compose -.->|"runs web"| node_django_entry
node_compose -.->|"runs"| node_postgres
node_compose -.->|"runs"| node_redis
node_compose -.->|"runs worker"| node_celery_config

click node_django_entry "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/manage.py"
click node_root_urls "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/urls.py"
click node_account_api "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/accounts/views.py"
click node_user_model "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/accounts/models.py"
click node_jwt "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/accounts/serializers.py"
click node_wallet_api "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/wallets/views.py"
click node_wallets "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/wallets/models.py"
click node_ledger_api "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/views.py"
click node_transfer_service "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/services.py"
click node_ledger_models "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/models.py"
click node_db_constraints "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/migrations/0001_initial.py"
click node_celery_config "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/celery.py"
click node_notification_task "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/tasks.py"
click node_settings "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/settings.py"
click node_compose "https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/docker-compose.yml"

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_django_entry,node_root_urls,node_account_api,node_user_model,node_jwt toneBlue
class node_wallet_api,node_wallets,node_ledger_api,node_transfer_service,node_ledger_models,node_db_constraints toneAmber
class node_celery_config,node_notification_task toneMint
class node_postgres,node_redis,node_settings,node_compose toneRose
```

## Components

### API & Identity

- [Django entry points](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/manage.py): runtime entry · CLI, ASGI, and WSGI start the API runtime. · `tradeledger/manage.py`
- [Global URL routing](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/urls.py): Django routing · `tradeledger/config/urls.py`
- [Accounts API](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/accounts/views.py): Django app · Registration, login, and profile endpoints. · `tradeledger/apps/accounts/views.py`
- [Custom user](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/accounts/models.py): identity model · `tradeledger/apps/accounts/models.py`
- [JWT authentication](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/accounts/serializers.py): auth boundary · Access and refresh tokens protect financial operations. · `tradeledger/apps/accounts/serializers.py`

### Wallet & Ledger

- [Wallet API](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/wallets/views.py): Django app · Exposes wallet balance and simulated top-up. · `tradeledger/apps/wallets/views.py`
- [Wallet balances](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/wallets/models.py): derived balance model · Mutable operational balances, not the accounting source of truth. · `tradeledger/apps/wallets/models.py`
- [Transfer & statement API](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/views.py): Django app · Transfer, transaction-history, and raw ledger-entry views. · `tradeledger/apps/ledger/views.py`
- [Transfer service](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/services.py): money movement service · Atomically orchestrates idempotency, locking, balances, and double-entry posting. · `tradeledger/apps/ledger/services.py`
- [Transactions & entries](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/models.py): immutable ledger models · One transaction records paired DEBIT and CREDIT entries that net to zero. · `tradeledger/apps/ledger/models.py`
- [Schema constraints](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/migrations/0001_initial.py): Django migrations · Database-enforced idempotency and financial schema invariants. · `tradeledger/apps/ledger/migrations/0001_initial.py`

### Async Delivery

- [Celery runtime](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/celery.py): worker configuration · `tradeledger/config/celery.py`
- [Transaction notifications](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/apps/ledger/tasks.py): Celery task · Runs after completed financial persistence. · `tradeledger/apps/ledger/tasks.py`

### Runtime Infrastructure

- **PostgreSQL**: primary database · Durable authority for transactions, row locks, and constraints.
- **Redis**: broker, backend & cache
- [Application settings](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/config/settings.py): Django configuration · Configures database, Redis cache, and runtime integrations. · `tradeledger/config/settings.py`
- [Docker Compose](https://github.com/smyanverma/tradeledger/blob/MAIN/tradeledger/docker-compose.yml): deployment composition · Runs web, PostgreSQL, Redis, and Celery worker processes. · `tradeledger/docker-compose.yml`

## Connections

- Django entry points → Global URL routing: serves
- Global URL routing → Accounts API: routes to
- Global URL routing → Wallet API: routes to
- Global URL routing → Transfer & statement API: routes to
- Accounts API → Custom user: creates and reads
- Accounts API → Wallet balances: provisions empty wallet
- JWT authentication → Wallet API: authorizes
- JWT authentication → Transfer & statement API: authorizes
- Wallet API → Wallet balances: reads and tops up
- Transfer & statement API → Transfer service: submits transfers
- Transfer & statement API → Transactions & entries: reads statements
- Transfer service → Wallet balances: locks and updates · Locks both wallets in stable order before balance changes.
- Transfer service → Transactions & entries: creates paired entries
- Transfer service → Schema constraints: relies on idempotency
- Wallet balances → PostgreSQL: persists in
- Transactions & entries → PostgreSQL: persists in
- Schema constraints → PostgreSQL: enforced by
- Transfer service → Transaction notifications: dispatches after completion
- Celery runtime → Transaction notifications: loads
- Transaction notifications → Redis: uses broker/backend
- Application settings → PostgreSQL: configures
- Application settings → Redis: configures cache
- Docker Compose → Django entry points: runs web
- Docker Compose → PostgreSQL: runs
- Docker Compose → Redis: runs
- Docker Compose → Celery runtime: runs worker
