Betting wallet and financial ledger¶
Тип материала — референсная архитектура. HYPOTHETICAL — проектные схемы и контракты. INFERENCE — рекомендации и trade-offs.
Бизнес-задача¶
Предотвратить двойной расход и связать каждую выплату с исходной ставкой.
Функциональные требования¶
Разделить booked, holds, available и withdrawable. Вести balanced journals по валюте и историю корректировок.
NFR и критический путь¶
Spend guard читает авторитетное состояние. UI projection может отставать. Сверка и backfill работают вне критического пути.
Компоненты и поток¶
flowchart LR
A["Wallet command"] --> B["Position guard"] --> C["Journal and holds"] --> D["Balance projection"] --> E["Reconciliation"]
Контракты и владельцы состояния¶
Ledger owns postings, hold store owns reserves. Запись содержит wallet, currency, amount_minor, bet_id и stable operation_id.
Транзакционные границы¶
Hold и bet в одной transaction либо durable reserve с конечным pending protocol. Settlement capture/release и posting атомарны в ledger.
Ordering, deduplication и idempotency¶
Lock wallet row либо serializable retry всей transaction. Idempotency key scoped tenant и типом операции. Rebuild проверяет generation.
Отказ и восстановление¶
При рестарте прочитать pending holds, сопоставить с bet outcome. Expiry не освобождает accepted hold без бизнес-основания.
Сверка¶
Пересчитать booked и outstanding reserves на одном cut. Сверить каждую payout instruction с journal.
Мониторинг и алерты¶
Negative available, orphan holds, duplicate operation conflicts, projection lag. Для каждого сигнала определить scope, cut и действие оператора. Порог подбирается по согласованному бюджету и наблюдаемой нагрузке.
Технологии и trade-offs¶
Ledger-first позволяет восстановить projections. Синхронная позиция в том же commit уменьшает стоимость spend check ценой hot rows.
Вопросы на собеседовании¶
Почему read replica не подходит для spend guard? Отстающий balance пропустит конфликтующий расход.