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

GET /api/v1/platform/commission-terms — Реестр условий платформенной комиссии

Постраничный реестр условий удержания ПИН (черновики, действующие, архив) с фильтрами по специфичности, агентству, застройщику, проекту, группе планировок, статусу и срезу «действовали на момент». Дом модели элемента PlatformCommissionTermsModel — здесь; операции правки/активации ссылаются сюда.

Назначение

Менеджер ПИН просматривает картину монетизации: какие условия действуют и запланированы по каждой комбинации измерений (агентство × ось объекта) и глобально, что в черновиках, какова история смен удержания. Owning-контекст — rewards, дом полей — domain/platform-commission-terms.md. Feature group — platform-terms.

Metadata

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

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

ПроверкаЗначение
Actor typeUser (Менеджер ПИН)
Auth policy / Permissionsrewards.platform-terms.view
Scope (RBAC)платформа
Tenant isolationвне tenant-модели — платформенные сущности (ADR-0052); выдача не фильтруется по tenant
Auditnone (read; агентствам реестр недоступен — применённое удержание они видят в снапшоте начисления)

HTTP-контракт

ПолеЗначение
MethodGET
Route/api/v1/platform/commission-terms
Success status200
Idempotency headerне применяется (read)
Correlationсквозной trace через заголовок traceparent

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

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
StatusqueryPlatformCommissionTermsStatus?Нетenum Draft/Active/Archived; unknown-значение → ValidationError
ScopequeryPlatformTermsScope?Нетenum AgencyLayoutGroup/LayoutGroup/AgencyProject/Project/AgencyDeveloper/Developer/Agency/Global — фильтр по заполненности измерений (не хранимое поле)
AgencyCompanyIdqueryGuid?Нетточное совпадение измерения AgencyCompanyId (условия с null под фильтр не попадают)
DeveloperCompanyIdqueryGuid?Нетточное совпадение измерения DeveloperCompanyId (условия с null под фильтр не попадают)
ProjectIdqueryGuid?Нетточное совпадение измерения ProjectId (условия с null под фильтр не попадают)
LayoutGroupIdqueryGuid?Нетточное совпадение измерения LayoutGroupId (условия с null под фильтр не попадают)
ActiveAsOfqueryDateTimeOffset?Нетсрез «действуют на момент»: Status = Active + период покрывает момент (EffectiveFrom <= ActiveAsOf и (EffectiveTo is null или EffectiveTo > ActiveAsOf)) — семантика резолюции; если Status не задан — применяется неявно Status = Active; если задан Status ≠ Active — параметр игнорируется (период применим только к действующим условиям)
Page / PageSizequeryintНетpaging-конвенция — README.md

Модель ответа ListPlatformTermsResult

ПолеТипОбязательностьИсточникMaskingОписание
ItemsIReadOnlyList<PlatformCommissionTermsModel>ДаprojectionСтраница условий.
Page / PageSizeintДаecho запросаПараметры страницы.
TotalCountlongДаCOUNT(*) по фильтруВсего записей под фильтром.

PlatformCommissionTermsModel (полная проекция PlatformCommissionTermsEntity — дом полей: domain/platform-commission-terms.md)

ПолеТипОбязательностьИсточникОписание
IdGuidДаIdId условий.
AgencyCompanyIdGuid?НетAgencyCompanyIdАгентство; null — по всем агентствам.
DeveloperCompanyIdGuid?НетDeveloperCompanyIdЗастройщик; null — по всем застройщикам.
ProjectIdGuid?НетProjectIdПроект; null — по всем проектам.
LayoutGroupIdGuid?НетLayoutGroupIdГруппа планировок; null — по всем группам.
Scopestring (enum PlatformTermsScope)Даcomputed из измеренийУровень специфичности (AgencyLayoutGroupGlobal).
RetentionPercentagePointsdecimalДаRetentionPercentagePointsУдержание ПИН, п.п. ставки застройщика (0.25–1.50).
EffectiveFromDateTimeOffsetДаEffectiveFromНачало периода действия.
EffectiveToDateTimeOffset?НетEffectiveToКонец периода (исключительно); null — бессрочно.
Commentstring?НетCommentКомментарий Менеджера ПИН.
Statusstring (enum PlatformCommissionTermsStatus)ДаStatusDraft/Active/Archived.
CreatedAtDateTimeOffsetДаCreatedAtМомент создания.
CreatedByUserIdGuid?НетCreatedByUserIdАвтор.
UpdatedAtDateTimeOffsetДаUpdatedAtМомент последнего изменения.
UpdatedByUserIdGuid?НетUpdatedByUserIdПоследний изменивший.
VersionlongДаVersionВерсия — для ExpectedVersion операций правки.

Алгоритм

  1. Контекст и доступ. Операцию выполняет Менеджер ПИН в платформенном scope; требуется право rewards.platform-terms.view.
  2. Проверка входа. Enum Status/Scope, диапазоны paging — иначе ValidationError.
  3. Выборка. Постранично отбираются условия с фильтрами: Status; Scope (по заполненности измерений); точные совпадения AgencyCompanyId/DeveloperCompanyId/ProjectId/LayoutGroupId; срез ActiveAsOf (семантика резолюции: активные с покрывающим периодом). Сортировка — EffectiveFrom DESC, CreatedAt DESC.
  4. Результат. Страница PlatformCommissionTermsModel (Items, Page, PageSize, TotalCount) → 200. Freshness — source of truth, без кэша.

Ошибки и failure modes

Общие коды (ValidationError, FORBIDDEN, UNAUTHORIZED) — README.md. Специфичных нет.

Acceptance-критерии

  • Happy path. Дано: записи условий в разных статусах и специфичностях, актор с rewards.platform-terms.view. Когда: GET /api/v1/platform/commission-terms?page=1. Тогда: 200, страница полных PlatformCommissionTermsModel с вычисленным Scope, сортировка EffectiveFrom DESC, CreatedAt DESC; TotalCount — число под фильтром.
  • Фильтр по специфичности. Дано: ?scope=Global. Когда: GET. Тогда: только записи со всеми измерениями null; ?scope=AgencyProject — только с заданными AgencyCompanyId/DeveloperCompanyId/ ProjectId и LayoutGroupId = null.
  • История агентства. Дано: ?agencyCompanyId=X. Когда: GET. Тогда: записи с измерением AgencyCompanyId = X (все уровни оси объекта); глобальные и по-всем-агентствам записи под фильтр не попадают — фильтр по измерению, не по применимости.
  • Действуют на момент. Дано: ?activeAsOf=T без Status. Когда: GET. Тогда: только активные условия, чей период покрывает T (неявно Status = Active) — картина резолюции на момент T; внутри каждой комбинации измерений — не более одной записи (INV-PT-2).
  • ActiveAsOf с неактивным статусом. Дано: ?activeAsOf=T&status=Archived. Когда: GET. Тогда: ActiveAsOf игнорируется; выдача — по остальным фильтрам.
  • Пустой результат. Дано: под фильтр не подходит ни одна запись. Когда: GET. Тогда: 200, Items = [], TotalCount = 0.
  • Неизвестный enum. Дано: ?status=Foo (или ?scope=Foo). Когда: GET. Тогда: 400 ValidationError.

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

  • Новые optional фильтры/поля модели — additive; enum PlatformCommissionTermsStatus/PlatformTermsScope расширяются только additive (клиент игнорирует unknown при чтении).
  • Logs: фильтры, TotalCount; metrics: rewards_api_request_duration_seconds{route}; traces: OTel; dashboard rewards-overview.
  • НФТ (ADR-0056): записей — единицы на комбинацию измерений + глобальный дефолт; выборка тривиальна, p95 < 200 мс.

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

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

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