checkAdminHeadcount(); } /** * Verifie qu'il restera au moins un admin apres la suppression de $user. * * Meme principe que ensureAtLeastOneAdminRemainsAfterDemotion() : $user * est accepte pour la symetrie du contrat et les evolutions futures, * mais le comptage ne depend pas de son identite. */ public function ensureAtLeastOneAdminRemainsAfterDeletion(User $user): void { $this->checkAdminHeadcount(); } /** * Compte les administrateurs et leve une exception si le seuil minimum est atteint. * * La verification est volontairement conservative (<=1) pour couvrir * le cas defensif ou la base serait deja dans un etat incoherent (0 admin). * * TOCTOU accepte : la verification n'utilise pas de verrou pessimiste * (SELECT ... FOR UPDATE). Deux demotions concurrentes pourraient donc * passer le garde simultanement. Ce risque est accepte dans le contexte * PME/CRM ou les operations d'administration sont rares et mono-operateur. * Si la concurrence admin devient un enjeu, ajouter un verrou pessimiste * sur countAdmins() ou une contrainte CHECK en base. * * @throws LastAdminProtectionException si le nombre d'admins est inferieur ou egal a 1 */ private function checkAdminHeadcount(): void { if ($this->userRepository->countAdmins() <= 1) { throw new LastAdminProtectionException(); } } }