# WalletLedger

OTP application implementing the double-entry posting engine within the MercuryPay umbrella.

## Public Interface

```elixir
# Post a balanced journal
WalletLedger.post_journal(entries_spec, reference_id, opts)

# Debit authorization hold
WalletLedger.authorize_debit(account_id, amount, currency, reference_id, opts)

# Apply a credit
WalletLedger.apply_credit(account_id, amount, currency, reference_id, opts)

# Reverse a posting
WalletLedger.reverse_posting(original_journal_id, reversal_reference_id, opts)

# Query balance
WalletLedger.get_balance(account_id, currency)

# Query history
WalletLedger.get_history(account_id, opts)
```

## Responsibilities
- Double-entry posting with balance invariant enforcement.
- Idempotent posting via reference_id deduplication.
- Balance queries: real-time debit/credit/net per account/currency.
- Paginated ledger history per account.
- Reversal: compensating journals with all directions flipped.
- Freeze checks: frozen accounts reject debits, allow credits.

## Invariants
1. Sum of debit amounts == sum of credit amounts per journal.
2. All entries in a journal share the same currency.
3. All entry amounts are positive integers (minor units, no floats).
4. reference_id is globally unique (idempotency key).
5. A journal may only be reversed once.

## Forbidden Dependencies
- `wallet_accounts` account lifecycle mutations (read-only reference is acceptable).
- Direct write to wallet_accounts tables.
- `wallet_auth` — no auth logic.

## Dependencies
- `wallet_shared_kernel` — TypedId, Money, Correlation.
- `wallet_api_contracts` — error codes.
- `wallet_observability` — AuditEvent, Telemetry.
- `wallet_events` — DomainEvent behaviour.
- `wallet_accounts` — read-only account status for freeze checks.
- `phoenix_pubsub` — domain event broadcast.

## TypedId Prefixes
- `jnl_` — ledger journals.
- `ent_` — ledger entries.

## Events Emitted
- `LedgerPosted.v1`
- `LedgerReversed.v1`
- `BalanceUpdated.v1`

## Store
`WalletLedger.LedgerStore` — ETS-backed GenServer with four tables. No database required for CI.

## ADR References
- ADR 0002 — Event naming conventions.
- ADR 0007 — Audit event requirements.
