# ayshasharaf/double-entry-ledger architecture

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

- Interactive diagram: https://gitdiagram.com/ayshasharaf/double-entry-ledger
- Repository: https://github.com/ayshasharaf/double-entry-ledger

## Overview

DoubleLedger is a REST ledger service: callers create accounts, submit balanced multi-leg postings, read balances and transaction history, and reverse entries. The controller hashes requests and delegates posting or reversal through idempotency handling; posting validates and persists journal legs, while account and transaction reads assemble responses from stored records. PostgreSQL is the source of truth, with advisory and row locks protecting concurrent work. The graph follows README capabilities and sampled calls; unsampled wiring is omitted.

Main entry points: [`ledger/src/main/java/com/doubleledger/ledger/service/LedgerPostingService.java`](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/LedgerPostingService.java) (Posting and reversal), [`ledger/src/main/java/com/doubleledger/ledger/controller/LedgerController.java`](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/controller/LedgerController.java) (Ledger controller), [`ledger/src/main/java/com/doubleledger/ledger/service/IdempotencyService.java`](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/IdempotencyService.java) (Idempotency service), [`ledger/src/main/java/com/doubleledger/ledger/service/JournalEntryResponseService.java`](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/JournalEntryResponseService.java) (Journal responses)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["HTTP API"]
  node_controller["Ledger controller"]
  node_exceptions["Exception mapping"]
end

subgraph group_domain["Ledger operations"]
  node_accounts["Account service"]
  node_balances["Balance service"]
  node_posting["Posting and reversal"]
  node_responses["Journal responses"]
end

subgraph group_data["Persistence"]
  node_account_repo["Account repository"]
  node_journal_repo["Journal repository"]
  node_ledger_repo["Ledger repository"]
  node_idem_repo["Idempotency repository"]
end

subgraph group_safety["Reliability"]
  node_hasher["Request hasher<br/>[RequestHasher.java]"]
  node_idempotency["Idempotency service"]
  node_lock["Advisory locks"]
  node_audit["Forensic audit"]
  node_async_audit["Async audit logger"]
end

node_caller(("API client"))
node_postgres[("PostgreSQL")]

node_caller -->|"calls REST API"| node_controller
node_controller -->|"manages accounts"| node_accounts
node_controller -->|"hashes requests"| node_hasher
node_controller -->|"guards writes"| node_idempotency
node_controller -->|"reads entries"| node_posting
node_controller -->|"reads transaction"| node_responses
node_controller -->|"maps failures"| node_exceptions
node_idempotency -->|"invokes action"| node_posting
node_idempotency -->|"builds response"| node_responses
node_idempotency -->|"reads and writes cache"| node_idem_repo
node_idempotency -->|"locks key"| node_lock
node_accounts -->|"reads and writes accounts"| node_account_repo
node_accounts -->|"computes responses"| node_balances
node_balances -->|"sums entries"| node_ledger_repo
node_posting -->|"locks accounts"| node_account_repo
node_posting -->|"reads and writes journals"| node_journal_repo
node_posting -->|"reads and writes legs"| node_ledger_repo
node_posting -->|"checks balances"| node_balances
node_posting -->|"serializes operations"| node_lock
node_posting -->|"reports failures"| node_audit
node_responses -->|"loads journal"| node_journal_repo
node_responses -->|"loads legs"| node_ledger_repo
node_audit -->|"dispatches failures"| node_async_audit
node_account_repo -->|"persists accounts"| node_postgres
node_journal_repo -->|"persists journals"| node_postgres
node_ledger_repo -->|"persists ledger legs"| node_postgres
node_idem_repo -->|"persists replay cache"| node_postgres
node_lock -->|"acquires advisory lock"| node_postgres

click node_controller "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/controller/LedgerController.java"
click node_exceptions "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/controller/GlobalExceptionHandler.java"
click node_accounts "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/AccountService.java"
click node_balances "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/AccountBalanceService.java"
click node_posting "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/LedgerPostingService.java"
click node_responses "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/JournalEntryResponseService.java"
click node_hasher "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/util/RequestHasher.java"
click node_idempotency "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/IdempotencyService.java"
click node_lock "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/persistence/PostgresAdvisoryLockService.java"
click node_audit "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/audit/ForensicAuditService.java"
click node_async_audit "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/audit/AsyncForensicAuditLogger.java"
click node_account_repo "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/AccountRepository.java"
click node_journal_repo "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/JournalEntryRepository.java"
click node_ledger_repo "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/LedgerEntryRepository.java"
click node_idem_repo "https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/IdempotencyKeyRepository.java"

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_controller,node_exceptions,node_caller toneBlue
class node_accounts,node_balances,node_posting,node_responses,node_postgres toneAmber
class node_account_repo,node_journal_repo,node_ledger_repo,node_idem_repo toneMint
class node_hasher,node_idempotency,node_lock,node_audit,node_async_audit toneRose
```

## Components

### HTTP API

- [Ledger controller](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/controller/LedgerController.java): `ledger/src/main/java/com/doubleledger/ledger/controller/LedgerController.java`
- [Exception mapping](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/controller/GlobalExceptionHandler.java): `ledger/src/main/java/com/doubleledger/ledger/controller/GlobalExceptionHandler.java`

### Ledger operations

- [Account service](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/AccountService.java): `ledger/src/main/java/com/doubleledger/ledger/service/AccountService.java`
- [Balance service](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/AccountBalanceService.java): `ledger/src/main/java/com/doubleledger/ledger/service/AccountBalanceService.java`
- [Posting and reversal](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/LedgerPostingService.java): `ledger/src/main/java/com/doubleledger/ledger/service/LedgerPostingService.java`
- [Journal responses](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/JournalEntryResponseService.java): `ledger/src/main/java/com/doubleledger/ledger/service/JournalEntryResponseService.java`

### Persistence

- [Account repository](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/AccountRepository.java): `ledger/src/main/java/com/doubleledger/ledger/repository/AccountRepository.java`
- [Journal repository](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/JournalEntryRepository.java): `ledger/src/main/java/com/doubleledger/ledger/repository/JournalEntryRepository.java`
- [Ledger repository](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/LedgerEntryRepository.java): `ledger/src/main/java/com/doubleledger/ledger/repository/LedgerEntryRepository.java`
- [Idempotency repository](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/repository/IdempotencyKeyRepository.java): `ledger/src/main/java/com/doubleledger/ledger/repository/IdempotencyKeyRepository.java`

### Reliability

- [Request hasher](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/util/RequestHasher.java): `ledger/src/main/java/com/doubleledger/ledger/util/RequestHasher.java`
- [Idempotency service](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/service/IdempotencyService.java): `ledger/src/main/java/com/doubleledger/ledger/service/IdempotencyService.java`
- [Advisory locks](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/persistence/PostgresAdvisoryLockService.java): `ledger/src/main/java/com/doubleledger/ledger/persistence/PostgresAdvisoryLockService.java`
- [Forensic audit](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/audit/ForensicAuditService.java): `ledger/src/main/java/com/doubleledger/ledger/audit/ForensicAuditService.java`
- [Async audit logger](https://github.com/ayshasharaf/double-entry-ledger/blob/main/ledger/src/main/java/com/doubleledger/ledger/audit/AsyncForensicAuditLogger.java): `ledger/src/main/java/com/doubleledger/ledger/audit/AsyncForensicAuditLogger.java`

### Other components

- **API client**
- **PostgreSQL**

## Connections

- API client → Ledger controller: calls REST API
- Ledger controller → Account service: manages accounts
- Ledger controller → Request hasher: hashes requests
- Ledger controller → Idempotency service: guards writes
- Ledger controller → Posting and reversal: reads entries
- Ledger controller → Journal responses: reads transaction
- Ledger controller → Exception mapping: maps failures
- Idempotency service → Posting and reversal: invokes action
- Idempotency service → Journal responses: builds response
- Idempotency service → Idempotency repository: reads and writes cache
- Idempotency service → Advisory locks: locks key
- Account service → Account repository: reads and writes accounts
- Account service → Balance service: computes responses
- Balance service → Ledger repository: sums entries
- Posting and reversal → Account repository: locks accounts
- Posting and reversal → Journal repository: reads and writes journals
- Posting and reversal → Ledger repository: reads and writes legs
- Posting and reversal → Balance service: checks balances
- Posting and reversal → Advisory locks: serializes operations
- Posting and reversal → Forensic audit: reports failures
- Journal responses → Journal repository: loads journal
- Journal responses → Ledger repository: loads legs
- Forensic audit → Async audit logger: dispatches failures
- Account repository → PostgreSQL: persists accounts
- Journal repository → PostgreSQL: persists journals
- Ledger repository → PostgreSQL: persists ledger legs
- Idempotency repository → PostgreSQL: persists replay cache
- Advisory locks → PostgreSQL: acquires advisory lock
