POST /api/v1/platform/referral-rate-rules/{rateRuleId}/archive — Архивирование ставки реферального вознаграждения
Перевод ставки Draft | Active → Archived: ставка навсегда выводится из резолюции. Снапшоты
применённой ставки в созданных реферальных начислениях (AppliedRateSnapshot) остаются живыми —
domain/referral-rate-rule.md.
Назначение
Менеджер ПИН немедленно выводит ставку из работы (в отличие от досрочного завершения через EffectiveTo
— архив действует сразу и безвозвратно) либо списывает ненужный черновик. Owning-контекст — rewards.
Feature group — referral-rates.
| Поле | Значение |
|---|
| Сервис/контекст | rewards |
| API area | platform |
| Feature group | referral-rates |
| Статус | draft |
| Документ | docs/06-services/rewards/api/platform/archive-referral-rate-rule.md |
Актор и доступ
| Проверка | Значение |
|---|
| Actor type | User (Менеджер ПИН) |
| Auth policy / Permissions | rewards.referral-rates.manage |
| Scope (RBAC) | платформа |
| Tenant isolation | вне tenant-модели — платформенная сущность (ADR-0052) |
| Audit | update: UpdatedByUserId, Version + 1, доменное событие ReferralRateRuleArchivedEvent |
HTTP-контракт
| Поле | Значение |
|---|
| Method | POST |
| Route | /api/v1/platform/referral-rate-rules/{rateRuleId}/archive |
| Success status | 200 |
| Idempotency header | не применяется (повтор из Archived → REWARDS_REFERRAL_RATE_INVALID_STATUS_TRANSITION) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|
ActorUserId | identity claims (sub) | Guid | Да | Required | — |
RateRuleId | route {rateRuleId} | Guid | Да | Required, непустой | — |
ExpectedVersion | body | long | Да | >= 1; сверка с Version | optimistic concurrency |
Модель ответа ArchiveReferralRateRuleResult
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|
Id | Guid | Да | ReferralRateRuleEntity.Id | — | Id ставки. |
Status | string (enum ReferralRateRuleStatus) | Да | Status | — | Всегда Archived. |
Version | long | Да | Version | — | Новая версия. |
Предусловия и постусловия
- Предусловия. Актор — Менеджер ПИН с
rewards.referral-rates.manage; ставка существует в статусе
Draft или Active; клиент передаёт актуальный ExpectedVersion.
- Постусловия (успех). Ставка в статусе
Archived, Version увеличен, актор зафиксирован; ставка
навсегда исключена из резолюции — новые начисления её комбинации измерений резолвятся в следующего
кандидата той же комбинации (по периоду) либо на менее специфичный уровень; если кандидатов не остаётся
ни
на одном уровне — реферальное начисление не создаётся, растёт warn-метрика
rewards_referral_accrual_no_rate_total (domain/referral-rate-rule.md,
«Резолюция ставки», шаг 4). Созданные начисления и их снапшоты (AppliedRateSnapshot.RateRuleId)
остаются живыми — физического удаления нет.
- Постусловия (отказ). Ставка без изменений.
Алгоритм
- Контекст и доступ. Операцию выполняет Менеджер ПИН в платформенном scope; требуется право
rewards.referral-rates.manage.
- Проверка входа и предусловий.
RateRuleId непустой, ExpectedVersion >= 1. Ставка существует —
иначе REWARDS_REFERRAL_RATE_NOT_FOUND. Статус ∈ {Draft, Active}; из Archived —
REWARDS_REFERRAL_RATE_INVALID_STATUS_TRANSITION. Version совпадает с ExpectedVersion — иначе
REWARDS_CONCURRENCY_CONFLICT. Наличие начислений со снапшотом ставки архив не блокирует.
- Переход и запись. Ставка переходит в
Archived; фиксируются актор и новая версия.
- Результат.
Id, Status = Archived, новый Version → 200. Интеграционные события не
публикуются.
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|
REWARDS_REFERRAL_RATE_NOT_FOUND | 404 | Ставка не существует | «Ставка не найдена» | no retry |
REWARDS_REFERRAL_RATE_INVALID_STATUS_TRANSITION | 409 | Уже Archived | «Ставка уже в архиве» | no retry |
REWARDS_CONCURRENCY_CONFLICT | 409 | ExpectedVersion устарел | «Ставка изменена другим пользователем» | retry после refresh |
Общие коды — README.md.
Acceptance-критерии
- Архив действующей ставки. Дано: ставка
Active, по ней созданы начисления. Когда: POST .../archive. Тогда: 200, Status = Archived, Version + 1; новые начисления ставку не применяют;
созданные начисления и их AppliedRateSnapshot не изменяются.
- Архив последней ставки уровня. Дано: архивируется единственная активная ставка специфичности;
менее специфичные уровни есть. Когда:
POST .../archive + завершение сделки её комбинации измерений.
Тогда: резолюция выбирает менее специфичный уровень («специфичное побеждает» продолжает работать вниз
по уровням).
- Архив последней ставки вообще. Дано: других активных ставок нет ни на одном уровне. Когда:
POST .../archive + завершение сделки с активным бондом. Тогда: реферальное начисление не создаётся,
растёт rewards_referral_accrual_no_rate_total (страховка — бессрочная Global-ставка).
- Архив черновика. Дано: ставка в
Draft. Когда: POST .../archive. Тогда: 200; резолюция не
затронута (черновик в ней не участвовал).
- Повторный архив. Дано: ставка уже
Archived. Когда: POST .../archive. Тогда: 409
REWARDS_REFERRAL_RATE_INVALID_STATUS_TRANSITION.
- Конкурентная версия. Дано:
ExpectedVersion устарел. Когда: POST. Тогда: 409
REWARDS_CONCURRENCY_CONFLICT.
Совместимость и наблюдаемость
- Архив терминален — восстановление не проектируется (создаётся новый черновик копированием значений +
активация; период новой ставки не должен пересекаться с оставшимися активными — INV-RR-2).
- Для планового завершения предпочтительно досрочное завершение через
EffectiveTo
(update-referral-rate-rule.md) — оно сохраняет ставку действующей до
границы; архив — немедленный вывод (ошибочно заведённая ставка, отмена акции «прямо сейчас»).
- Logs:
ActorUserId, RateRuleId, исходный статус, Scope; metrics:
rewards_referral_rate_archive_total{result}; warn-метрика последствий —
rewards_referral_accrual_no_rate_total; traces: OTel; dashboard rewards-overview.
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные документы