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

GET /api/v1/platform/referral-accruals — Реестр реферальных начислений

Постраничный реестр реферальных начислений платформы для Менеджера ПИН: кому (партнёр), за какую сделку и по какой ставке начислено вознаграждение, в каком статусе жизненного цикла оно находится (domain/referral-accrual.md) — с фильтрами по партнёру, застройщику, статусу и периоду сделок.

Назначение

Менеджер ПИН контролирует реферальную программу: сколько начислено и ожидает получения денег (Pending), сколько готово к выплате (Approved), выплачено (Paid) и отменено (Cancelled) — и находит начисления для ручного разбора (отмена по фроду/ошибке — cancel-referral-accrual.md). Партнёр свои начисления смотрит отдельной операцией partner-области (rewards.referral.view-own, record-level). Feature group — referral-accruals.

Metadata

ПолеЗначение
Сервис/контекстrewards
API areaplatform
Feature groupreferral-accruals
Статусdraft
Документdocs/06-services/rewards/api/platform/list-referral-accruals.md

Актор и доступ

ПроверкаЗначение
Actor typeUser (Менеджер ПИН)
Auth policy / Permissionsrewards.accruals.manage (каталог — permission.md)
Scope (RBAC)платформа
Tenant isolationвне tenant-модели — реферальные начисления платформенные (ADR-0052); агентствам и застройщикам не отдаются
Auditread-sensitive (суммы вознаграждений): в trace — actor + фильтры + TotalCount; суммы не логируются

HTTP-контракт

ПолеЗначение
MethodGET
Route/api/v1/platform/referral-accruals
Success status200
Correlationсквозной trace через заголовок traceparent

Входные данные / параметры запроса

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
PartnerUserIdqueryGuid?Нетнепустой Guid, если задан
DeveloperCompanyIdqueryGuid?Нетнепустой Guid, если задан
StatusqueryReferralAccrualStatus?Нетenum Pending/Approved/Paid/Cancelled
DealCompletedFromqueryDateTimeOffset?Нетнижняя граница DealCompletedAt (включительно)
DealCompletedToqueryDateTimeOffset?Нетверхняя граница DealCompletedAt (исключительно); > DealCompletedFrom, если обе заданы
Page / PageSizequeryintНетpaging-конвенция — README.md (Page >= 1, PageSize 1..100)

Модель ответа — постраничный список ReferralAccrualModel

Постраничный ответ: Items (список ReferralAccrualModel), Page, PageSize, TotalCount (paging-конвенция — README.md). ReferralAccrualModel — полная проекция начисления, дом модели — этот документ (дом полей — domain/referral-accrual.md); операции области ссылаются сюда и описывают только дельту.

ПолеТипОбязательностьИсточникMaskingОписание
IdGuidДаReferralAccrualEntity.IdId начисления.
DealIdGuidДаDealIdСделка crm (одно начисление на сделку, INV-RA-1).
BondIdGuidДаBondIdРеферальная связь — основание начисления.
PartnerUserIdGuidДаPartnerUserIdПартнёр — получатель вознаграждения.
DeveloperCompanyIdGuidДаDeveloperCompanyIdЗастройщик сделки.
CommissionAccrualIdGuid?НетCommissionAccrualIdРодительское комиссионное начисление; null — родитель не создан, гейт денег непроходим.
BaseAmountMoneyModelДаBaseAmountSensitiveБаза расчёта — конечная цена сделки.
AmountMoneyModelДаAmountSensitiveСумма вознаграждения (INV-RA-2; после first-class корректировки — скорректированная, INV-RA-6).
OriginalAmountMoneyModel?НетOriginalAmountSensitiveИсходная сумма до корректировок; null — сумма не корректировалась (INV-RA-6).
AppliedRateAppliedRateModelДаAppliedRateSnapshot (jsonb)Снапшот применённой ставки (модель ниже).
Statusstring (enum ReferralAccrualStatus)ДаStatusСтатус жизненного цикла.
DealCompletedAtDateTimeOffsetДаDealCompletedAtМомент завершения сделки (asOf резолюции ставки).
ApprovedAtDateTimeOffset?НетApprovedAtМомент авто-апрува (регистрация акта родителя).
PaidAtDateTimeOffset?НетPaidAtМомент выплаты.
CancelledAtDateTimeOffset?НетCancelledAtМомент отмены.
CancelReasonstring? (enum ReferralCancelReason)НетCancelReasonПричина отмены (DealCancelled/BondRevoked/ManualCorrection).
PayoutOrderItemIdGuid?НетPayoutOrderItemIdПозиция реферального поручения; null — начисление свободно.
CreatedAtDateTimeOffsetДаCreatedAtМомент создания.
VersionlongДаVersionДля ExpectedVersion мутаций (отмена).

InvestorUserId в проекцию не выносится (PII приведённого инвестора; трассировка — через DealId в crm, Masking-правила README.md).

AppliedRateModel (проекция AppliedRateSnapshotDocument)

ПолеТипОбязательностьИсточникОписание
RateRuleIdGuidДаснапшотСтавка на момент применения (domain/referral-rate-rule.md).
Scopestring (enum ReferralRateScope)ДаснапшотPartnerDeveloper/Partner/Developer/Global.
PercentdecimalДаснапшотПрименённый процент от FinalPrice.
EffectiveFrom / EffectiveToDateTimeOffset / DateTimeOffset?Да / НетснапшотПериод ставки на момент применения.

Алгоритм

Тривиальное постраничное чтение: проверить право rewards.accruals.manage (иначе FORBIDDEN) и параметры фильтра (enum Status, DealCompletedTo > DealCompletedFrom, paging — иначе ValidationError); прочитать страницу начислений по фильтрам PartnerUserId / DeveloperCompanyId / Status / границы DealCompletedAt (логическое И; опорные индексы — ix_referral_accruals_partner, ix_referral_accruals_developer, ix_referral_accruals_status, ix_referral_accruals_deal_completed_at) с сортировкой DealCompletedAt DESC; спроецировать в ReferralAccrualModel и вернуть 200. Чтение строго согласовано с записью: авто-апрув по регистрации акта виден в реестре сразу.

Ошибки и failure modes

Специфичных REWARDS_*-кодов у read-операции нет; общие коды (ValidationError 400 — Status вне enum, границы периода перепутаны, PageSize вне 1..100; FORBIDDEN 403; UNAUTHORIZED 401) — дом README.md «Общие ошибки».

Acceptance criteria

  • AC-1 (реестр). Given есть начисления в разных статусах по нескольким партнёрам; When Менеджер ПИН запрашивает список без фильтров; Then 200, начисления по DealCompletedAt DESC, у каждого — партнёр, застройщик, Amount, снапшот ставки (Scope, Percent), статус и даты переходов; InvestorUserId отсутствует.
  • AC-2 (фильтры). Given те же данные; When заданы PartnerUserId и/или DeveloperCompanyId и/или Status = Approved и/или границы периода; Then в выдаче только строки под все условия одновременно; DealCompletedFrom включителен, DealCompletedTo исключителен.
  • AC-3 (готовые к выплате). Given фильтр Status = Approved; Then видны кандидаты в реферальное поручение; у уже включённых PayoutOrderItemId != null — оператор видит, какие начисления свободны.
  • AC-4 (пустой результат). Given нет начислений под фильтр или Page за последней страницей; Then 200, Items = [], корректный TotalCount (не 404).
  • AC-5 (валидация фильтра). Given Status вне enum или DealCompletedTo <= DealCompletedFrom; Then ValidationError (400).
  • AC-6 (доступ). Given актор без rewards.accruals.manage (в т.ч. руководитель агентства, менеджер застройщика, сам партнёр); When запрос; Then FORBIDDEN (403) — платформенный реестр; партнёру доступна только собственная выборка partner-области (record-level PartnerUserId).
  • AC-7 (свежесть). Given только что зарегистрирован акт поступления (register-platform-receipt.md); When сразу запрошен реестр; Then апрувнутые рефералки уже в статусе Approved (строгая согласованность внутри rewards).

Совместимость и наблюдаемость

  • ReferralAccrualModel — дом этого документа: новые optional-поля — additive; удаление/переименование/ смена типа — breaking. Новые значения ReferralAccrualStatus/ReferralCancelReason — по unknown-enum-правилу.
  • Logs: фильтры (PartnerUserId, DeveloperCompanyId, Status, границы), TotalCount (суммы не логируются); metrics: rewards_api_request_duration_seconds{route}; traces: OTel, correlation через traceparent; dashboard rewards-overview.
  • НФТ (ADR-0056): начислений — доли завершённых сделок (десятки тысяч в год); выборка по btree-индексам; целевая латентность p95 < 250 мс; частота обращений низкая (back-office Менеджера ПИН).

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

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

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