Skip to content

REL-7: Инварианты администратора #93

Description

@ii-reviewer

Цель: не дать системе остаться без единого активного ADMIN.
Зависимость: USR-1.

Что сделать

  • Запретить деактивацию последнего активного ADMIN → внятная ошибка (например 409 LAST_ADMIN).
  • Запретить деактивацию самого себя — SelfDeactivationException уже есть: проверить, что реально срабатывает на DELETE /api/users/{id}, покрыт тестом, и маппится в правильный код в GlobalExceptionHandler.
  • Проверку «последний админ» делать устойчиво к гонке (см. стретч), а не наивным count() до апдейта.
  • Стретч: гонка — два параллельных запроса деактивируют двух последних админов одновременно; оба проходят наивную проверку count(active admins) > 1 и оставляют 0 админов. Решить через блокировку/атомарный conditional UPDATE/сериализацию, не через «проверил-потом-обновил».

Acceptance criteria

  • Деактивация единственного активного ADMIN → отказ, он остаётся активным.
  • Деактивация себя → отказ (SelfDeactivationException → корректный HTTP-код).
  • При двух активных админах одного деактивировать можно.
  • Конкурентный тест: два запроса на двух последних админов → выживает хотя бы один админ (минимум один запрос отклонён).
  • Тесты на все инварианты, включая гонку.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecurityБезопасность, защита эндпоинтов

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions