GET /api/v1/platform/commission-terms — Реестр условий платформенной комиссии
Постраничный реестр условий удержания ПИН (черновики, действующие, архив) с фильтрами по специфичности,
агентству, застройщику, проекту, группе планировок, статусу и срезу «действовали на момент». Дом модели
элемента PlatformCommissionTermsModel — здесь; операции правки/активации ссылаются сюда.
Назначение
Менеджер ПИН просматривает картину монетизации: какие условия действуют и запланированы по каждой
комбинации измерений (агентство × ось объекта) и глобально, что в черновиках, какова история смен
удержания. Owning-контекст — rewards, дом полей —
domain/platform-commission-terms.md. Feature group —
platform-terms.
| Поле | Значение |
|---|
| Сервис/контекст | rewards |
| API area | platform |
| Feature group | platform-terms |
| Статус | draft |
| Документ | docs/06-services/rewards/api/platform/list-platform-terms.md |
Актор и доступ
| Проверка | Значение |
|---|
| Actor type | User (Менеджер ПИН) |
| Auth policy / Permissions | rewards.platform-terms.view |
| Scope (RBAC) | платформа |
| Tenant isolation | вне tenant-модели — платформенные сущности (ADR-0052); выдача не фильтруется по tenant |
| Audit | none (read; агентствам реестр недоступен — применённое удержание они видят в снапшоте начисления) |
HTTP-контракт
| Поле | Значение |
|---|
| Method | GET |
| Route | /api/v1/platform/commission-terms |
| Success status | 200 |
| Idempotency header | не применяется (read) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|
Status | query | PlatformCommissionTermsStatus? | Нет | enum Draft/Active/Archived; unknown-значение → ValidationError | — |
Scope | query | PlatformTermsScope? | Нет | enum AgencyLayoutGroup/LayoutGroup/AgencyProject/Project/AgencyDeveloper/Developer/Agency/Global — фильтр по заполненности измерений (не хранимое поле) | — |
AgencyCompanyId | query | Guid? | Нет | точное совпадение измерения AgencyCompanyId (условия с null под фильтр не попадают) | — |
DeveloperCompanyId | query | Guid? | Нет | точное совпадение измерения DeveloperCompanyId (условия с null под фильтр не попадают) | — |
ProjectId | query | Guid? | Нет | точное совпадение измерения ProjectId (условия с null под фильтр не попадают) | — |
LayoutGroupId | query | Guid? | Нет | точное совпадение измерения LayoutGroupId (условия с null под фильтр не попадают) | — |
ActiveAsOf | query | DateTimeOffset? | Нет | срез «действуют на момент»: Status = Active + период покрывает момент (EffectiveFrom <= ActiveAsOf и (EffectiveTo is null или EffectiveTo > ActiveAsOf)) — семантика резолюции; если Status не задан — применяется неявно Status = Active; если задан Status ≠ Active — параметр игнорируется (период применим только к действующим условиям) | — |
Page / PageSize | query | int | Нет | paging-конвенция — README.md | — |
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|
Items | IReadOnlyList<PlatformCommissionTermsModel> | Да | projection | — | Страница условий. |
Page / PageSize | int | Да | echo запроса | — | Параметры страницы. |
TotalCount | long | Да | COUNT(*) по фильтру | — | Всего записей под фильтром. |
PlatformCommissionTermsModel (полная проекция PlatformCommissionTermsEntity — дом полей: domain/platform-commission-terms.md)
| Поле | Тип | Обязательность | Источник | Описание |
|---|
Id | Guid | Да | Id | Id условий. |
AgencyCompanyId | Guid? | Нет | AgencyCompanyId | Агентство; null — по всем агентствам. |
DeveloperCompanyId | Guid? | Нет | DeveloperCompanyId | Застройщик; null — по всем застройщикам. |
ProjectId | Guid? | Нет | ProjectId | Проект; null — по всем проектам. |
LayoutGroupId | Guid? | Нет | LayoutGroupId | Группа планировок; null — по всем группам. |
Scope | string (enum PlatformTermsScope) | Да | computed из измерений | Уровень специфичности (AgencyLayoutGroup…Global). |
RetentionPercentagePoints | decimal | Да | RetentionPercentagePoints | Удержание ПИН, п.п. ставки застройщика (0.25–1.50). |
EffectiveFrom | DateTimeOffset | Да | EffectiveFrom | Начало периода действия. |
EffectiveTo | DateTimeOffset? | Нет | EffectiveTo | Конец периода (исключительно); null — бессрочно. |
Comment | string? | Нет | Comment | Комментарий Менеджера ПИН. |
Status | string (enum PlatformCommissionTermsStatus) | Да | Status | Draft/Active/Archived. |
CreatedAt | DateTimeOffset | Да | CreatedAt | Момент создания. |
CreatedByUserId | Guid? | Нет | CreatedByUserId | Автор. |
UpdatedAt | DateTimeOffset | Да | UpdatedAt | Момент последнего изменения. |
UpdatedByUserId | Guid? | Нет | UpdatedByUserId | Последний изменивший. |
Version | long | Да | Version | Версия — для ExpectedVersion операций правки. |
Алгоритм
- Контекст и доступ. Операцию выполняет Менеджер ПИН в платформенном scope; требуется право
rewards.platform-terms.view.
- Проверка входа. Enum
Status/Scope, диапазоны paging — иначе ValidationError.
- Выборка. Постранично отбираются условия с фильтрами:
Status; Scope (по заполненности
измерений); точные совпадения AgencyCompanyId/DeveloperCompanyId/ProjectId/LayoutGroupId; срез
ActiveAsOf (семантика резолюции: активные с покрывающим периодом). Сортировка —
EffectiveFrom DESC, CreatedAt DESC.
- Результат. Страница
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 мс.
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные документы