DELETE /api/admin/notifications/templates/{templateId} — Архивировать шаблон
Назначение
Администратор платформы выводит шаблон уведомления
(NotificationTemplateEntity) из обращения: переводит его в
Status = Archived и проставляет DeletedAt (soft-delete). История уже отрисованных уведомлений не
затрагивается — они хранят собственный RenderedBody. Owning-контекст — notifications, feature group
templates.
| Поле | Значение |
|---|
| Сервис/контекст | notifications |
| API area | admin |
| Feature group | templates |
| Статус | draft |
| Документ | docs/06-services/notifications/api/admin/archive-template.md |
Актор и доступ
| Проверка | Значение |
|---|
| Actor type | Operator(Admin) |
| Auth policy / Permissions | notifications.templates.manage |
| Scope (RBAC) | платформа |
| Tenant isolation | не tenanted (платформенный каталог) |
| Audit | update/soft-delete (DeletedAt, DeletedByUserId, Version) |
HTTP-контракт
| Поле | Значение |
|---|
| Method | DELETE |
| Route | /api/admin/notifications/templates/{templateId} |
| Success status | 200 (архивировано; тело — итоговый статус) |
| Idempotency header | не применяется (повтор — no-op, уже Archived) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|
TemplateId | route | Guid | Да | существует | — |
ExpectedVersion | query | long? | Нет | optimistic concurrency | — |
Модель ответа TemplateModel
Та же модель, что в create-template.md (со Status = Archived).
Алгоритм
- Контекст и доступ. Операцию выполняет администратор платформы; требуется право
notifications.templates.manage; каталог шаблонов платформенный (не tenanted). Нет права → FORBIDDEN.
- Проверка входа и предусловий. Шаблон с
TemplateId должен существовать; иначе —
NTF_TEMPLATE_NOT_FOUND. Если задан ExpectedVersion и он не совпадает с текущей версией шаблона —
NTF_TEMPLATE_CONFLICT (правку нужно повторить, перечитав актуальную версию). Системный шаблон
(IsSystem = true, INV-TPL-4) архивировать нельзя — NTF_TEMPLATE_SYSTEM_LOCKED.
- Правила и переход. Перевести шаблон в
Status = Archived, проставить DeletedAt/DeletedByUserId
(soft-delete). Если шаблон уже Archived — операция ничего не меняет (повтор — no-op). После архивации
резолв шаблона при enqueue его больше не выбирает (INV-TPL-5).
- Согласованность. Смена статуса шаблона и инвалидация кэша резолва шаблонов (сигнал
TemplateChanged)
выполняются в одном согласованном изменении. Уже отрисованные уведомления не меняются.
- Результат. Возвращается карточка шаблона со
Status = Archived.
Диаграмма
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|
FORBIDDEN | 403 | нет notifications.templates.manage | «Недостаточно прав» | no retry |
NTF_TEMPLATE_NOT_FOUND | 404 | TemplateId не найден | «Шаблон не найден» | no retry |
NTF_TEMPLATE_SYSTEM_LOCKED | 409 | IsSystem-шаблон (INV-TPL-4) | «Системный шаблон нельзя архивировать» | no retry |
NTF_TEMPLATE_CONFLICT | 409 | ExpectedVersion не совпадает с текущей версией | «Повторите операцию» | retry (перечитать) |
Пред- и постусловия
- Предусловие. Актор авторизован и имеет
notifications.templates.manage; шаблон существует; он не
системный (IsSystem = false).
- Постусловие (успех). Шаблон в
Status = Archived, проставлены DeletedAt/DeletedByUserId, Version
увеличена; кэш резолва шаблонов инвалидирован — enqueue/консюмеры этот шаблон больше не выбирают (INV-TPL-5).
Уже отрисованные NotificationEntity неизменны (хранят собственный RenderedBody). Идемпотентно: повтор на
уже Archived шаблоне ничего не меняет и возвращает тот же результат.
Кросс-сервисное следствие
Архивация активного шаблона снимает единственный Active-шаблон пары (Kind, Locale) (по Code их не более
одного). После инвалидации кэша любой enqueue или consumer, которому нужен шаблон для этого Kind/Locale,
не сможет его резолвить и получит NTF_TEMPLATE_NOT_RESOLVED: для internal-enqueue — 422, для консюмеров —
DLQ + алерт (см. enqueue-notification.md,
../../consumers/crm-events.md). Перед архивацией единственного действующего
шаблона следует опубликовать замену или убедиться, что Kind больше не порождается. Fallback ru при
архивации нероссийской локали остаётся доступен, если ru-шаблон Active.
Совместимость и наблюдаемость
- Архивация — soft-delete (реверсируется через
update-template → Draft/Active). Logs:
template-archived (Code); metrics: notifications_templates_archived_total.
Acceptance criteria
- Given админ с
notifications.templates.manage и Active-шаблон, when архивирует его, then
200 со Status = Archived, шаблон исчезает из резолва (NTF_TEMPLATE_NOT_RESOLVED для новых enqueue этого
Kind), но существующие in-app/отправленные уведомления не меняются.
- Given уже
Archived шаблон, when архивируется повторно, then 200 (no-op), Version не растёт
повторно.
- Given системный шаблон (
IsSystem = true), when попытка архивации, then 409
NTF_TEMPLATE_SYSTEM_LOCKED, состояние не изменилось.
- Given передан устаревший
ExpectedVersion, when архивация, then 409 NTF_TEMPLATE_CONFLICT;
после перечитывания актуальной версии повтор проходит.
- Given актор без
notifications.templates.manage, when архивация, then 403 FORBIDDEN, шаблон
не тронут.
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные документы