Книга учёта
Hostra ведёт книгу учёта с двойной записью — это единственный источник истины о движении денег. Каждая операция — сбалансированный набор списаний и зачислений, записанные строки не меняются, а остатки вычисляются из записей, а не хранятся и не правятся вручную.
Почему двойная запись
Остаток в одной колонке может оказаться неверным, и никто этого не заметит: обновление применилось дважды, возврат записали, а комиссию — нет, и число в базе больше ничего не объясняет. При двойной записи ошибочное состояние просто невозможно: несбалансированная операция не фиксируется. А ответ на вопрос «почему остаток именно такой» — всегда список записей, из которых он сложился.
Модель
- Счёт
- Именованная позиция в плане счетов: остаток продавца, клиринг с провайдером, доход от комиссий, расходы сети.
- Запись
- Одно списание или зачисление по одному счёту: сумма, валюта и точность в минимальных единицах.
- Операция
- Набор записей, в котором сумма списаний и зачислений должна быть равна нулю, иначе операция не фиксируется.
- Правила проводок
- Однозначное соответствие между расчётным событием и записями: одно и то же событие всегда даёт одинаковые проводки.
- Остаток
- Значение, вычисленное из записей, а не изменяемый счётчик, который может разойтись с историей.
- Запись аудита
- Звено цепочки хешей по изменению состояния; её можно проверить через точку проверки аудита.
Свойства
- Сбалансированность: в каждой зафиксированной операции списания равны зачислениям.
- Неизменность: записи только добавляются и никогда не правятся. Исправление — это новая компенсирующая операция.
- Вычисляемые остатки: остаток выводится из записей, поэтому история и текущее состояние не могут расходиться.
- Минимальные единицы: суммы хранятся целыми числами в копейках и центах, без ошибок округления.
- Предсказуемость: одно и то же расчётное событие всегда даёт те же проводки, поэтому повторы безопасны.
- Проверяемость: каждое изменение продлевает защищённую цепочку хешей, которую можно проверить независимо.
Связь с расчётами
Книга учёта не обращается к провайдерам, а расчётный движок не придумывает бухгалтерию. Движок отвечает за жизненный цикл поручения — ожидает, в работе, выполнено, ошибка или отменено, — и каждый переход создаёт заранее определённые проводки. Поскольку движок фиксирует результат ровно один раз, книга учёта никогда не получает дубль проводки; а поскольку проводки предсказуемы, повтор события не может дать другой учётный результат.
Сверка
При сверке сравниваются три источника: что записано в книге учёта, какое итоговое состояние поручения зафиксировал расчётный движок и что сообщает провайдер или сеть. Записи неизменны и связаны цепочкой хешей, поэтому любое расхождение всегда указывает на конкретную операцию, а не на необъяснимую разницу в остатке. Расхождения устраняются компенсирующей операцией, и исходная история остаётся нетронутой.