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

GET /api/v1/agency/agent-boost-campaigns — Список boost-кампаний агентов

Список временных мотивационных кампаний агентства (действующие, черновики, архив) — экран «Boost-кампании» ЛК руководителя агентства. Boost поднимает долю набора агентов на период поверх базовой комиссионной политики.

Назначение

Руководитель агентства видит действующие и подготовленные кампании и историю свёрнутых. Feature group — agent-boost (операция op57 реестра README.md).

Metadata

ПолеЗначение
Сервис/контекстrewards
API areaagency
Feature groupagent-boost
Статусdraft
Документdocs/06-services/rewards/api/agency/list-agent-boost-campaigns.md

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

ПроверкаЗначение
Actor typeUser (руководитель/администратор агентства)
Auth policy / Permissionsrewards.commission-policy.view
Scope (RBAC)организация: компания Type ∈ {Agency, Broker, Pin}
Record-levelне применяется
Tenant isolationTenantId = CompanyId агентства из claims; tenant-интерсептор
Auditnone (read; ставки/наборы агентов — Internal-класс внутри агентства)

HTTP-контракт

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

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

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
TenantIdidentity claims (tenant_id)GuidДаRequiredTenant isolation
StatusqueryAgentBoostCampaignStatus?Нетenum Draft/Active/Archived
AgentUserIdqueryGuid?Нетопц. фильтр «кампании с этим агентом в наборе»
Page / PageSizequeryintНетpaging-конвенция — README.md

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

Постраничный ответ (Items, Page, PageSize, TotalCount — paging-конвенция README.md). Правило BoostRule и набор AgentUserIds отдаются только ролям с rewards.commission-policy.view/ rewards.commission-policy.manage (руководитель/администратор агентства); агент такой роли не имеет и на этот эндпоинт не попадает — действующий к нему boost он видит лишь в проекции «моя комиссия» (get-my-commission-summary.md, Masking-правила README.md).

AgentBoostCampaignModel (проекция AgentBoostCampaignEntity)

Дом формы — create-agent-boost-campaign.md; дом полей под-агрегата — domain/agency-commission-policy.md.

ПолеТипОбязательностьИсточникMaskingОписание
IdGuidДаIdId кампании.
NamestringДаNameНазвание («Весенний boost 7%»).
Descriptionstring?НетDescriptionОснование/условия.
Statusstring (enum AgentBoostCampaignStatus)ДаStatusDraft/Active/Archived.
BoostRuleAgencyRetentionRuleModelДаBoostRuleполное правило — только роли с rewards.commission-policy.viewПовышенная доля агента (Kind ∈ {AgentPercentOfPool, AgentPercentOfPrice}).
AgentUserIdsIReadOnlyList<Guid>ДаTargets.AgentUserIdsсписок агентов — только роли с rewards.commission-policy.viewНабор агентов кампании.
EffectiveFromDateTimeOffsetДаEffectiveFromНачало периода.
EffectiveToDateTimeOffset?НетEffectiveToКонец периода (исключительно); null — бессрочно.
CreatedAt / UpdatedAtDateTimeOffsetДаaudit-поляАудит.
VersionlongДаVersionДля ExpectedVersion мутаций.

Вложенная AgencyRetentionRuleModel (Kind/Value/CurrencyId?) — дом list-agency-policies.md; для boost Kind ограничен AgentPercentOfPool/AgentPercentOfPrice, CurrencyId = null.

Алгоритм

  1. Контекст и доступ. Операцию выполняет руководитель/администратор агентства; scope — организация (TenantId из claims); требуется право rewards.commission-policy.view.
  2. Проверка входа. Status — допустимое значение enum AgentBoostCampaignStatus, если задан; AgentUserId — валидный Guid, если задан; Page/PageSize — по конвенции; иначе ошибка валидации.
  3. Что читаем. Страница кампаний агентства-tenant-а: опц. фильтры по Status и AgentUserId (кампании, содержащие этого агента в наборе); сортировка детерминированная: Active выше, затем Draft/Archived по CreatedAt DESC (свежие черновики и последние архивы выше). Выборка по ix_agent_boost_campaigns_tenant_status. У агентства, ещё не заводившего кампаний, страница пуста (Items = [], TotalCount = 0) — это не ошибка.
  4. Проекция. Каждая кампания разворачивается в AgentBoostCampaignModel; документы BoostRule и Targets разворачиваются в BoostRule + AgentUserIds (ContractVersion наружу не отдаётся).
  5. Результат. Постраничный список AgentBoostCampaignModel (Items, Page, PageSize, TotalCount) → HTTP 200. Данные строго согласованы внутри rewards: список отражает последний коммит create/activate/archive немедленно (агрегатное чтение OLTP) — задержки eventual-consistency нет.

Диаграмма

Ошибки и failure modes

Специфичных REWARDS_*-кодов у read-операции нет (нет мутаций и concurrency). Применяются общие коды — дом README.md «Общие ошибки»:

КодHTTP statusУсловиеСообщениеRetry
ValidationError400Status вне enum AgentBoostCampaignStatus; PageSize вне 1..100«Проверьте параметры фильтра»no retry
UNAUTHORIZED401нет/просрочен JWT«Требуется авторизация»no retry
FORBIDDEN403нет rewards.commission-policy.view / тип компании вне {Agency, Broker, Pin} / чужой tenant«Недостаточно прав»no retry

Acceptance criteria

  • AC-1 (список кампаний). Given у агентства есть действующие и архивные кампании; When руководитель запрашивает список без фильтра; Then 200, Active выше, далее Draft/Archived по CreatedAt DESC; для каждой отданы BoostRule и AgentUserIds; ContractVersion в проекции отсутствует.
  • AC-2 (фильтр по статусу). Given те же данные; When запрос с Status = Active; Then возвращаются только действующие кампании; Status = Archived возвращает историю по CreatedAt DESC.
  • AC-3 (фильтр по агенту). Given кампании с разными наборами; When запрос с AgentUserId = X; Then только кампании, содержащие X в наборе.
  • AC-4 (нет кампаний → пусто). Given агентство ещё не заводило кампаний; When запрос списка; Then 200, Items = [], TotalCount = 0 (не 404).
  • AC-5 (недостаточно прав). Given актор без rewards.commission-policy.view или не роль агентства; When запрос; Then FORBIDDEN (403), список не раскрывается.
  • AC-6 (изоляция tenant). Given актор агентства A; When запрос; Then в выдаче только кампании A — TenantId берётся из claims, не из query; кампании агентства B недоступны.
  • AC-7 (свежесть). Given только что активирована новая кампания; When сразу запрошен список; Then новая Active уже в выдаче (строгая согласованность внутри rewards, без окна eventual-consistency).

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

  • Новые поля кампании — additive nullable; удаление/переименование/смена типа — breaking. Новые значения enum AgentBoostCampaignStatus в query — по unknown-enum-правилу cross-cutting (ValidationError).
  • Logs: TenantId, применённые фильтры, TotalCount (ставки/наборы не логируются — Internal-класс); metrics: rewards_api_request_duration_seconds{route}; traces: OTel, correlation через traceparent; dashboard rewards-overview.
  • НФТ (ADR-0056): единицы кампаний на агентство — выборка тривиальна; целевая латентность p95 < 200 мс; операция back-office (низкая частота).

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

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

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