UC-WLT-003. ПИН-админ вручную корректирует баланс
Назначение
Описывает сценарий ручной корректировки баланса кошелька администратором платформы: исправление
последствий рассинхрона или операционной ошибки (по итогам issue Reconciliation Center) добавлением
компенсирующей записи в журнал — с обязательной причиной и аудитом актора. Прямой правки баланса или
журнала не существует: корректировка — такая же транзакция двойной записи. Связан с контекстом wallet.
Metadata
| Поле | Значение |
|---|---|
| ID | UC-WLT-003 |
| Контекст | wallet (см. docs/06-services/wallet/) |
| Тип | исключительный (ручное исправление, не штатный денежный поток) |
| Статус | draft |
Актор
| Поле | Значение |
|---|---|
| Роль | Администратор платформы (ПИН-админ) |
| Permissions / scope | wallet.adjustments.manage, платформенный scope |
| Tenant | не применяется (платформенная операция над любым счётом) |
Предусловие
- Есть основание для корректировки: issue Reconciliation Center, результат разбора DLQ «дебет без покрытия» либо подтверждённая операционная ошибка (ADR-0021).
- Целевой счёт существует (wallet-account.md); для компенсации — известна исходная транзакция журнала.
Триггер
| Поле | Значение |
|---|---|
| Источник | API call |
| Триггерящий элемент | admin-операция create-wallet-adjustment.md (POST /api/v1/platform/wallet/adjustments) |
Основной Поток
- Админ находит счёт в admin-реестре (list-wallet-accounts.md,
wallet.accounts.view-all) и создаёт корректировку: сумма со знаком (положительная — увеличить баланс, отрицательная — уменьшить), обязательная причина, идемпотентный ключ операции. - Система проверяет вход: счёт существует (иначе
WALLET_ACCOUNT_NOT_FOUND— корректировка несуществующего счёта запрещена, счета создаются только кредитамиrewards), причина непуста (иначеWALLET_ADJUSTMENT_REASON_REQUIRED), сумма ненулевая, валюта равна валюте счёта (иначеWALLET_CURRENCY_MISMATCH). - Система проводит транзакцию
Adjustment(SourceId= идемпотентный ключ операции): увеличение — дебетPlatformSettlement/ кредит целевого счёта; уменьшение — зеркально (ledger-transaction.md, карта проводок). Причина — вComment, актор — вActorUserId. - Guard no-negative: уменьшение не может увести баланс холдерского счёта ниже нуля — иначе отказ
WALLET_BALANCE_NEGATIVE_FORBIDDEN(INV-WLT-3); системные счета могут уходить в минус. - Транзакция, проводки и балансы фиксируются атомарно; публикуется
pin.wallet.transaction-recorded.v1по проводке холдерского счёта. - Холдер получает уведомление «баланс скорректирован»; админ видит транзакцию в журнале счёта.
Альтернативные Потоки
A1. Повтор операции (двойная отправка формы / retry)
- Запрос с тем же идемпотентным ключом приходит повторно.
- Система обнаруживает существующую транзакцию
(Adjustment, SourceId)(INV-WLT-7) и возвращает её же как результат — вторая транзакция не проводится, баланс не меняется дважды.
A2. Компенсация транзакции (Correction) — не через этот сценарий
Зеркальная компенсация со ссылкой на исходную транзакцию (Correction) в v1 проводится только системно —
при отмене реферального начисления после Approved
(UC-WLT-001, A4). Ручного API-пути компенсации
нет: админ выражает исправление обычным Adjustment с причиной-ссылкой на разбор.
Постусловие
- В журнале появилась ровно одна append-only транзакция
Adjustmentс причиной и актором; прежние записи журнала не изменены. - Баланс целевого счёта изменён на сумму корректировки и (для холдерского) остался
>= 0; парная проводка легла наPlatformSettlement. Balanceкаждого затронутого счёта равен пересчёту из журнала.- Событие
pin.wallet.transaction-recorded.v1опубликовано; уведомление холдеру доставлено.
Возможные Ошибки
| Код | HTTP | Условие | Поведение клиента |
|---|---|---|---|
WALLET_ACCOUNT_NOT_FOUND | 404 | Целевой счёт не существует | Проверить выбор счёта |
WALLET_ADJUSTMENT_REASON_REQUIRED | 400 | Причина не указана / пустая | Заполнить причину |
WALLET_CURRENCY_MISMATCH | 400 | Валюта суммы ≠ валюте счёта (INV-WLT-4) | Исправить валюту (RUB-only, ADR-0048) |
WALLET_BALANCE_NEGATIVE_FORBIDDEN | 409 | Уменьшение увело бы холдерский баланс ниже нуля (INV-WLT-3) | Уменьшить сумму либо решать расхождение на стороне rewards |
ValidationError | 400 | Нулевая сумма / формат полей / нет идемпотентного ключа | Исправить запрос |
Kafka Интеграционные События
| Событие | Topic | Когда публикуется | Consumers |
|---|---|---|---|
WalletTransactionRecordedKafkaEvent | pin.wallet.transaction-recorded.v1 | Атомарно с проведением корректировки — по проводке холдерского счёта | notifications |
Acceptance Criteria
| # | Критерий | Проверка |
|---|---|---|
| AC1 | Given счёт агента с балансом B, When админ проводит увеличение на X с причиной, Then баланс = B + X, в журнале — транзакция Adjustment с причиной и актором, исходные записи не тронуты | интеграционный тест |
| AC2 | Given корректировка без причины, When запрос отправлен, Then отказ WALLET_ADJUSTMENT_REASON_REQUIRED и журнал не изменён | негативный тест |
| AC3 | Given уменьшение на сумму больше баланса холдерского счёта, When запрос отправлен, Then отказ WALLET_BALANCE_NEGATIVE_FORBIDDEN, баланс не изменён | негативный тест (INV-WLT-3) |
| AC4 | Given повторная отправка той же операции (тот же идемпотентный ключ), When запрос обработан, Then вторая транзакция не проведена, возвращена ранее проведённая, баланс изменён однократно | тест идемпотентности (INV-WLT-7) |
| AC5 | Given корректировка несуществующего счёта, When запрос отправлен, Then отказ WALLET_ACCOUNT_NOT_FOUND — счёт не создаётся | негативный тест |
| AC6 | Given любая корректировка, When она проведена, Then Balance затронутых счетов равен пересчёту из журнала | сверочный пересчёт (ADR-0021) |
Обратные ссылки
Автоссылки: где используется этот документ.
- Use Cases (3): UC-WLT-004. Холдер смотрит баланс и историю операций, UC-WLT-005. Оператор ПИН смотрит журнал проводок счёта (сверка), UC-WLT-006. Компенсирующее начисление отражается в балансе после MoneyReceived
- registries (1): Реестр use cases и user stories PIN
- index.md (1): Wallet Service
Связанные Документы
- Domain entity: ledger-transaction.md (виды
Adjustment/Correction, коды ошибок), wallet-account.md (INV-WLT-1..4). - API методы: create-wallet-adjustment.md, list-wallet-accounts.md.
- Производимое событие: wallet-transaction-recorded.md.
- Основания корректировок: ADR-0021; ADR-0065 п.4.