GET /api/v1/agency/wallet/agent-balances — Балансы агентов агентства
Назначение
Отдаёт руководителю агентства баланс счёта самого агентства (AgencyCommission) и постраничный список
AgentCommission-балансов агентов текущего состава: сколько каждому сотруднику начислено и ещё не
выплачено. Управленческий инструмент для планирования платёжных поручений
(rewards/domain/payout-order.md): баланс агента — это разница
между кредитами по гейту получения денег и уже проведёнными выплатами.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | wallet |
| API area | agency |
| Feature group | agency-wallet |
| Статус | draft |
| Документ | docs/06-services/wallet/api/agency/list-agency-agent-balances.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (руководитель агентства / роль с доступом к командным данным) |
| Auth policy / Permissions | wallet.team.view |
| Scope (RBAC) | организация (только своё агентство) |
| Record-level | счёт AgencyCommission компании актора + AgentCommission-счета агентов её текущего состава по display-реплике (см. «Границы выборки») |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/v1/agency/wallet/agent-balances |
| Success status | 200 |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения |
|---|---|---|---|---|
AgencyCompanyId | identity claims | Guid | Да | компания актора — граница выборки |
AgentUserId | query | Guid? | Нет | точечный фильтр по одному агенту |
Page / PageSize | query | int | Нет | paging — ../README.md |
Границы выборки
Текущий состав агентов агентства резолвится по локальной display-реплике холдеров
(../../domain/user-display-replica.md): агенты компании актора —
строки реплики с CompanyId = компания актора. Синхронного вызова identity на read-path нет — состав
реплицируется по событию pin.identity.user-upserted (смена агентства зеркалит CompanyId, ADR-0070),
консюмер ../../consumers/identity-users.md. Реплика eventual: только
что вступивший/вышедший агент попадает в ростер после применения snapshot-а (секунды, при лаге — минуты);
это допустимая косметическая гонка на управленческом чтении, а не риск «утечки» — сами балансы ведёт
журнал независимо от ростера, а доступ агента к своим данным отсекает identity (JWT).
Балансы user-centric и переживают смену агентства (../../domain/wallet-account.md):
руководитель видит весь остаток AgentCommission-счёта агента текущего состава, включая накопленное в
прежних агентствах. Разрез «сколько должно именно наше агентство» — это свободные Agent-строки
распределений в rewards (rewards/domain/commission-accrual.md),
не баланс кошелька.
Модель ответа AgencyWalletModel
| Поле | Тип | Обязательность | Источник | Описание |
|---|---|---|---|---|
AgencyBalance | WalletBalanceModel? | Нет | счёт AgencyCommission (HolderCompanyId = компания актора) | Баланс счёта агентства; null — счёт ещё не создан (кредитов не было). Дом модели — ../README.md. |
AgencyDisplayName | string? | Нет | display-реплика (CompanyName строк агентов компании актора) | Название агентства — подпись счёта AgencyCommission; null — компания ещё не реплицирована (user-display-replica.md). |
Agents | страница AgencyAgentBalanceModel | Да | счета агентов состава | Балансы агентов (paging-конверт — ../README.md). |
AgencyAgentBalanceModel
| Поле | Тип | Обязательность | Источник | Описание |
|---|---|---|---|---|
AgentUserId | Guid | Да | HolderUserId счёта | Агент — холдер счёта. |
HolderDisplayName | string? | Нет | display-реплика (DisplayName по AgentUserId) | ФИО агента для подписи строки; null — реплика ещё не наполнена (клиент показывает id). Резолв из реплики, без синхронного identity (user-display-replica.md). |
Balance | WalletBalanceModel | Да | счёт AgentCommission | Баланс счёта агента. |
LastTransactionAt | DateTimeOffset? | Нет | журнал (последняя проводка счёта) | Момент последнего движения — сигнал «давно не было выплат». |
Сортировка — Balance по убыванию (наибольшие невыплаченные остатки сверху). Агенты состава без счёта
(ни одного начисления, прошедшего гейт денег) в списке отсутствуют — их баланс равен нулю.
Алгоритм
- Определить компанию актора; permission
wallet.team.viewв scope организации — иначеFORBIDDEN. - Проверить фильтры и paging → при нарушении
ValidationError. - Получить текущий состав агентов компании из display-реплики (строки с
CompanyId= компания актора) — без синхронногоidentity. ЗаданныйAgentUserIdне входит в ростер реплики →FORBIDDEN(record-level). - Выбрать счёт
AgencyCommissionкомпании иAgentCommission-счета агентов ростера (при заданномAgentUserId— только его счёт), подтянуть подписи из реплики (DisplayNameагентов,CompanyNameагентства), спроецировать в модель ответа, вернуть страницу. Отсутствие строки реплики → подписьnull(клиент показывает id), не ошибка. История движений конкретного агента руководителю не отдаётся (только сам агент —wallet.transactions.view-own); детализация «за что начислено» — вrewardsпо своим permissions.
Ошибки и failure modes
Специфических ошибок нет: ростер берётся из локальной display-реплики, синхронного вызова identity на
read-path больше нет (прежний WALLET_MEMBERSHIP_UNAVAILABLE/503 устранён). Только общие ошибки области
(../README.md): ValidationError (400), UNAUTHORIZED (401), FORBIDDEN (403 — нет
permission / агент вне ростера реплики / выборка вне своей организации). Пустой/устаревший ростер
(лаг консюмера) ошибкой не является — 200 с текущим состоянием реплики.
Совместимость и наблюдаемость
- Новые optional-поля модели — additive.
- Logs: запрос без сумм (
AgencyCompanyId, число строк); metrics: латентность p95; traces —traceparent.
Обратные ссылки
Автоссылки: где используется этот документ.
- Домен (CQRS) (2): Entity (Replica): UserDisplayReplicaEntity, Entity / Aggregate: WalletAccountEntity
- API (2): POST /api/v1/agency/wallet/statement-exports — Постановка выписки по счёту агентства/агента (XLSX), Wallet API — реестр операций и общие контрактные модели
- Use Cases (1): UC-WLT-004. Холдер смотрит баланс и историю операций
- Консюмеры (1): Consumer: Wallet Identity Display Sync (wallet-identity-users)
- registries (1): Реестр API-методов PIN
- index.md (1): Wallet Service
Связанные документы
- Счета (user-centric, виды, холдеры): ../../domain/wallet-account.md; источник кредитов: ../../consumers/rewards-commission-money-received.md.
- Выплаты агентам: rewards/domain/payout-order.md
(
PayoutOrderKind = AgencyCommission). - Ростер и подписи (display-реплика): ../../domain/user-display-replica.md, консюмер ../../consumers/identity-users.md.
- Общие модели и ошибки: ../README.md; карта зависимостей — ../../README.md.