Перейти к основному содержимому

UC-WLT-005. Оператор ПИН смотрит журнал проводок счёта (сверка)

Назначение

Описывает сценарий финансового контроля: оператор ПИН открывает постраничный журнал проводок произвольного счёта кошелька — холдерского (AgentCommission/ReferralCommission/AgencyCommission) или системного (PlatformSettlement/PlatformRevenue) — чтобы разобрать инцидент рассинхрона, проверить счёт перед ручной корректировкой и после неё, свериться «баланс = журнал» и аудировать движение средств. В отличие от истории личного кошелька (UC-WLT-004), platform-журнал не ограничен холдером и раскрывает служебные атрибуты: причину и актора ручной операции (Adjustment), причину компенсации (Correction), направление, сумму и баланс-после каждой проводки. Чтение — read-only; журнал append-only. Связан с контекстом wallet.

Metadata

ПолеЗначение
IDUC-WLT-005
Контекстwallet (см. docs/06-services/wallet/)
Типосновной
Статусdraft

Актор

ПолеЗначение
РольОператор/администратор ПИН
Permissions / scopewallet.accounts.view-all, платформенный scope
Tenantне применяется (платформенная операция над любым счётом, включая системные)
Record-levelнет — оператор видит журнал любого счёта

Предусловие

  • Оператор авторизован и имеет wallet.accounts.view-all.
  • Целевой счёт существует (wallet-account.md); обычно выбирается из admin-реестра счетов (list-wallet-accounts.md).
  • По счёту есть хотя бы одна проводка (иначе журнал пуст — не ошибка).

Триггер

ПолеЗначение
ИсточникUI
Триггерящий элементadmin-реестр счетов → счёт → «Журнал проводок»; либо разбор issue Reconciliation Center

Основной Поток

  1. Оператор находит счёт в admin-реестре и открывает его журнал (list-account-ledger.md, GET /api/v1/platform/wallet/accounts/{accountId}/ledger), опционально задаёт фильтры: вид операции (WalletOperationKind), период (From/To), пагинация.
  2. Система проверяет доступ и существование счёта (нет счёта → WALLET_ACCOUNT_NOT_FOUND), корректность фильтров (вид вне enum / From >= To / paging вне диапазона → ValidationError).
  3. Система отдаёт страницу проводок этого счёта из журнала (ledger-transaction.md), присоединяя атрибуты их транзакций. По каждой строке (WalletLedgerEntryModel): вид операции; Debit или Credit (разнесены по полям, бухгалтерский вид; заполнено ровно одно, суммы > 0); BalanceAfter (сальдо счёта сразу после проводки, зафиксировано при проведении); SourceId — непрозрачная ссылка-основание (расшифровка — в rewards по своим permissions); для Adjustment/ CorrectionComment (причина) и ActorUserId (кто провёл ручную операцию), для CorrectionCorrectedTransactionId; OccurredAt (момент бизнес-факта) и RecordedAt (момент проведения). Сортировка — RecordedAt по убыванию, внутри момента — по EntryId (стабильные страницы).
  4. Оператор сверяет: последняя (свежайшая) BalanceAfter равна текущему Balance счёта из реестра; при полном обходе Balance = Σ Credit − Σ Debit проводок счёта. Сходимость подтверждает целостность; расхождение — сигнал инцидента (A2).

Альтернативные Потоки

A1. Системный счёт (PlatformSettlement/PlatformRevenue)

  1. Оператор открывает журнал транзитного PlatformSettlement: баланс штатно <= 0 (INV-WLT-3; |Balance| = объём средств, разнесённых по получателям и ещё не погашенных выплатами), в журнале — дебеты по кредитам получателям и кредиты по выплатам. PlatformRevenue — доход ПИН, кредитуется Platform-строками. Проводки системных счетов события transaction-recorded не порождают, но в журнале видны полностью.

A2. Обнаружено расхождение баланса (сверка не сошлась)

  1. Пересчёт Σ Credit − Σ Debit по журналу не равен хранимому Balance счёта → инцидент рассинхрона (ADR-0021, метрика wallet_balance_drift_total). Журнал первичен: баланс восстанавливается пересчётом из журнала, журнал не правится. Из этого сценария оператор только диагностирует; исправление — пересчёт баланса и/или компенсирующая транзакция (UC-WLT-003), но не в рамках чтения журнала.

A3. Аудит ручных операций (фильтр Adjustment/Correction)

  1. Оператор фильтрует журнал по OperationKind = Adjustment (или Correction), чтобы проверить все ручные вмешательства: по каждой строке видны причина (Comment), актор (ActorUserId) и, для Correction, исходная компенсируемая транзакция (CorrectedTransactionId). Журнал сам является audit trail.

A4. Основание проводки нужно расшифровать

  1. SourceId отдаётся как непрозрачная ссылка (id начисления / реферального начисления / позиции поручения / исходной транзакции / ключа корректировки — карта видов в ledger-transaction.md). Расшифровка «что за сделка/начисление» — в rewards по permissions оператора там; wallet соответствия «сумма ↔ клиент/сделка» в этой проекции не раскрывает.

A5. Счёт без проводок

  1. По счёту ещё не было ни одной проводки (например, только что созданный системный) → пустая страница; интерфейс показывает «Операций нет». Не ошибка.

Постусловие

  • Состояние системы не изменено (read-only): мутаций, транзакций и событий нет.
  • Показанные проводки согласованы с журналом; при полном обходе сумма направлений сходится с балансом счёта (или зафиксировано расхождение — A2).
  • Факт обращения к журналу залогирован (актор, AccountId, фильтры — без сумм; read-sensitive аудит).

Возможные Ошибки

КодHTTPУсловиеПоведение клиента
WALLET_ACCOUNT_NOT_FOUND404Счёта с указанным AccountId не существуетВернуться к реестру счетов
ValidationError400OperationKind вне enum / From >= To / paging вне диапазонаИсправить фильтры
FORBIDDEN403Нет wallet.accounts.view-all«Недостаточно прав»
UNAUTHORIZED401Нет/просрочен JWT«Требуется авторизация»

Acceptance Criteria

#КритерийПроверка
AC1Given счёт с проводками, When оператор открывает журнал, Then каждая строка показывает вид, Debit/Credit (ровно одно), BalanceAfter, OccurredAt/RecordedAt; сортировка — свежие сверхуинтеграционный тест
AC2Given полный обход журнала счёта, When суммируются направления, Then Σ Credit − Σ Debit = текущему Balance; последняя BalanceAfter = Balanceсверочный тест (ADR-0021)
AC3Given ручная операция, When она в журнале, Then видны Comment (причина) и ActorUserId; для CorrectionCorrectedTransactionId (A3)тест раскрытия служебных полей
AC4Given системный счёт PlatformSettlement, When оператор смотрит журнал, Then баланс <= 0 трактуется по INV-WLT-3, проводки видны полностью (A1)тест системного счёта
AC5Given несуществующий AccountId, When запрос журнала, Then WALLET_ACCOUNT_NOT_FOUND (404)негативный тест
AC6Given фильтр по виду операции/периоду, When применён, Then выборка ограничена корректно; неверный фильтр → ValidationErrorтест фильтров
AC7Given чтение журнала, When операция завершена, Then состояние не изменено и факт обращения залогирован без суммread-only + аудит

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные Документы