GET /api/v1/reward-rules — Список правил вознаграждений застройщика
Постраничный список правил вознаграждений компании-застройщика с фильтрами по статусу и базе расчёта — экран «Правила вознаграждений» админки застройщика.
Назначение
Менеджер застройщика просматривает набор правил (черновики, действующие, архив), чтобы управлять
таблицей решений комиссий. Owning-контекст — rewards, дом полей —
domain/reward-rule.md. Feature group — rules.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | rewards |
| API area | developer-admin |
| Feature group | rules |
| Статус | draft |
| Документ | docs/06-services/rewards/api/admin/list-reward-rules.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (менеджер компании-застройщика) |
| Auth policy / Permissions | rewards.rules.view |
| Scope (RBAC) | организация: компания Type = Developer |
| Record-level | не применяется (все правила tenant-а) |
| Tenant isolation | TenantId = CompanyId застройщика из claims; tenant-интерсептор SDK фильтрует выборку |
| Audit | none (read, несенситивные данные класса Internal) |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/v1/reward-rules |
| Success status | 200 |
| Idempotency header | не применяется (read) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
TenantId | identity claims (tenant_id) | Guid | Да | Required | Tenant isolation |
Status | query | RewardRuleStatus? | Нет | enum Draft/Active/Archived; unknown-значение → ValidationError | — |
CalculationBase | query | CommissionCalculationBase? | Нет | enum BasePrice/FinalPrice | — |
ProjectId | query | Guid? | Нет | фильтр по ЖК: правила, у которых Conditions.ProjectIds содержит ProjectId (правила-акции на конкретный ЖК). Правила-default (ProjectIds пуст) под фильтр не попадают (у них нет привязки к ЖК) | — |
EffectiveAt | query | DateTimeOffset? | Нет | фильтр «действует на момент»: (EffectiveFrom is null or <= EffectiveAt) and (EffectiveTo is null or > EffectiveAt); применяется только совместно со Status = Active. Если задан без Status = Active — параметр игнорируется (период проверяется лишь для действующих правил), остальные фильтры действуют | — |
SearchText | query | string? | Нет | <= 256; ILIKE %text% по Name | trusted boundary: параметризованный запрос |
Page / PageSize | query | int | Нет | paging-конвенция — README.md | — |
Модель ответа ListRewardRulesQueryResult
Страница RewardRuleModel — модель элемента целиком по дому
(README.md «Общие контрактные модели»), без дельты: список отдаёт полные правила,
включая Conditions (условий немного, отдельная get-операция нужна для точечного refresh).
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
Items | IReadOnlyList<RewardRuleModel> | Да | projection | — | Страница правил. |
Page / PageSize | int | Да | echo запроса | — | Параметры страницы. |
TotalCount | long | Да | COUNT(*) по фильтру | — | Всего правил под фильтром. |
Алгоритм
- Контекст и доступ. Операцию выполняет менеджер компании-застройщика; scope — организация
застройщика (
TenantId); требуется правоrewards.rules.view. Выборка ограничена tenant-ом застройщика. - Проверка входа. Enum
Status/CalculationBase, длинаSearchText, диапазоны paging — иначеValidationError. - Выборка. Постранично отбираются правила tenant-а: по умолчанию неудалённые (для
Status = Archived— наоборот, архивные), опционально с фильтрами поStatus,CalculationBase, принадлежности ЖКProjectId(вхождение вConditions.ProjectIds), периодуEffectiveAtи поиском поName(регистронезависимо, параметризованный запрос). Сортировка —Priority DESC, CreatedAt DESC(совпадает с порядком победы при подборе правила). - Проекция. Каждая строка отдаётся как
RewardRuleModelцеликом, включаяConditions. - Результат. Страница правил (
Items,Page,PageSize,TotalCount) →200. Freshness — source of truth, без кэша.
Диаграмма
Ошибки и failure modes
Общие коды (ValidationError, FORBIDDEN, UNAUTHORIZED) — README.md. Специфичных нет.
Acceptance-критерии
- Happy path. Дано: у застройщика есть правила в разных статусах, актор с
rewards.rules.view. Когда:GET /api/v1/reward-rules?page=1. Тогда:200, страница неархивных правилRewardRuleModel, отсортированнаяPriority DESC, CreatedAt DESC;TotalCount— число под фильтром. - Фильтр по статусу. Дано:
?status=Active. Когда:GET. Тогда: только действующие правила;?status=Archived— только архивные (иначе архив в выдачу не попадает). - Действует на момент. Дано:
?status=Active&effectiveAt=T. Когда:GET. Тогда: только активные правила, чей период включаетT(EffectiveFrom <= T < EffectiveTo, с учётомnull-границ). EffectiveAtбезStatus=Active. Дано:?effectiveAt=Tбезstatus=Active(или сstatus=Draft/Archived). Когда:GET. Тогда:EffectiveAtигнорируется (период применим только к действующим правилам); выдача формируется по остальным фильтрам.- Фильтр по ЖК. Дано:
?projectId=<ЖК-X>. Когда:GET. Тогда: только правила, у которыхConditions.ProjectIdsсодержитЖК-X(акции/ставки на этот ЖК); правила-default без привязки к ЖК в выдачу не попадают. - Поиск по имени. Дано:
?searchText=парков. Когда:GET. Тогда: правила, чьёNameсодержит подстроку без учёта регистра; специальные символы не ломают выборку (параметризованный запрос). - Пустой результат. Дано: под фильтр не подходит ни одно правило. Когда:
GET. Тогда:200,Items = [],TotalCount = 0. - Неизвестный enum. Дано:
?status=Foo. Когда:GET. Тогда:400ValidationError. - Чужой tenant не виден. Дано: у другого застройщика есть правила. Когда:
GET. Тогда: они в выдаче не появляются (изоляция по tenant).
Совместимость и наблюдаемость
- Новые optional фильтры/поля модели — additive; enum
RewardRuleStatusрасширяется только additive (клиент обязан игнорировать unknown при чтении). - Logs:
TenantId, фильтры,TotalCount(суммы в списке не логируются); metrics:rewards_api_request_duration_seconds{route}; traces: OTel; dashboardrewards-overview; runbook — не применяется.
Обратные ссылки
Автоссылки: где используется этот документ.
- API (2): POST /api/v1/reward-rules — Создание правила вознаграждения (черновик), Rewards API — реестр операций и общие контрактные модели
- registries (1): Реестр API-методов PIN
Связанные документы
- Сущность: domain/reward-rule.md; модель — README.md.
- Соседние операции: get-reward-rule.md, create-reward-rule.md.