Манитон Docs

Ledger-DB Service

Система операционного учета и двойной записи

Ledger-DB Service (В разработке)

Статус: В активной разработке (Sprint 1). Проектируется как проекция DLT-данных для быстрого доступа.

Ledger-DB — это критический компонент платформы, отвечающий за операционный учет денежных средств и ЦФА. Он реализует модель двойной записи (Double-Entry Bookkeeping).

Архитектура учета

Система учета построена на следующих сущностях:

  1. Account: Глобальный счет пользователя или системы.
  2. SubAccount: Субсчет для конкретного актива (RUB, CFA-EQ, и т.д.).
  3. Operation: Группировка проводок, представляющая собой одну бизнес-операцию (например, "Торговля").
  4. Posting: Атомарная запись о движении средств между двумя субсчетами.
  5. Hold: Временная блокировка средств (например, под открытый ордер).

Технологический стек

  • Фреймворк: NestJS
  • База данных: PostgreSQL
  • ORM: Drizzle ORM
  • Связь: gRPC (для синхронных проверок) + Kafka (для асинхронного обновления).

Принципы работы

  • Атомарность: Все проводки внутри одной Operation выполняются в одной транзакции БД.
  • Неизменяемость: Существующие проводки нельзя удалять или изменять. Для исправления ошибок используются сторнирующие (reversing) записи.
  • Double Contour: Ledger-DB является проекцией данных из DLT (Besu), но также хранит промежуточные состояния (Hold), которых нет в блокчейне.

Модель данных (Entity-Relationship)

Loading diagram...

Модель данных (Protobuf)

message Account {
  string account_id = 1;
  string user_id = 2;
  AccountType type = 3;  // MAIN / INVEST / BLOCKED
}

message SubAccount {
  string subaccount_id = 1;
  string account_id = 2;
  string instrument_id = 3;  // CFA-RUB / CFA-EQ-001 / ...
  Decimal balance = 4;
  SubAccountStatus status = 5;
}

message Operation {
  string operation_id = 1;
  OperationType type = 2;
  OperationStatus status = 3;
  string user_id = 4;
  string idempotency_key = 5;
  string external_ref = 6;
  string onchain_tx_hash = 7;
}

message Posting {
  string posting_id = 1;
  string operation_id = 2;
  string debit_subaccount_id = 3;
  string credit_subaccount_id = 4;
  MonetaryAmount amount = 5;
}

message Hold {
  string hold_id = 1;
  string subaccount_id = 2;
  MonetaryAmount amount = 3;
  HoldStatus status = 4;  // ACTIVE / RELEASED / CONSUMED / EXPIRED
  string reason = 5;
}

Пример проводок

Пополнение (Deposit):

Debit:  System.Reserve.CFA-RUB      +1000
Credit: User123.Main.CFA-RUB        +1000

Покупка инвест-ЦФА:

Debit:  User123.Main.CFA-RUB        -5000
Credit: System.Reserve.CFA-RUB      +5000

Debit:  System.Reserve.CFA-EQ-001   -10 shares
Credit: User123.Invest.CFA-EQ-001   +10 shares

On this page