package dev.lions.unionflow.server.service; import dev.lions.unionflow.server.entity.MembreOrganisation; import dev.lions.unionflow.server.entity.MembreRole; import dev.lions.unionflow.server.repository.MembreRoleRepository; import dev.lions.unionflow.server.repository.RoleRepository; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.transaction.Transactional; import java.time.LocalDate; import org.jboss.logging.Logger; /** * Synchronise le rôle DB (MembreRole) avec le rôle Keycloak au premier accès. * *

Lorsqu'un utilisateur est admin dans Keycloak (rôle {@code ADMIN_ORGANISATION}) * mais n'a pas encore de ligne {@code MembreRole ORGADMIN} en base, ce service la * crée à la volée. Cela couvre deux cas : *

    *
  1. Comptes créés directement dans Keycloak sans passer par * {@code MembreService#promouvoirAdminOrganisation}.
  2. *
  3. Bases de données en dev qui ont démarré avant la migration V30.
  4. *
*/ @ApplicationScoped public class MembreRoleSyncService { private static final Logger LOG = Logger.getLogger(MembreRoleSyncService.class); @Inject MembreRoleRepository membreRoleRepository; @Inject RoleRepository roleRepository; @PersistenceContext EntityManager entityManager; /** * Assure qu'un MembreRole ORGADMIN existe pour ce MembreOrganisation. * Idempotent : sans effet si l'entrée existe déjà. * * @param mo MembreOrganisation de l'admin (non null) */ @Transactional public void ensureOrgAdminRole(MembreOrganisation mo) { if (mo == null || mo.getId() == null || mo.getOrganisation() == null) { return; } // Vérifier si un MembreRole ORGADMIN actif existe déjà pour ce membre dans cette org long existing = membreRoleRepository.count( "membreOrganisation.id = ?1 AND role.code = ?2 AND actif = true", mo.getId(), "ORGADMIN"); if (existing > 0) { return; // Déjà en place — rien à faire } // Chercher le rôle ORGADMIN dans la table roles roleRepository.findByCode("ORGADMIN").ifPresentOrElse( role -> { MembreRole mr = new MembreRole(); mr.setMembreOrganisation(mo); mr.setOrganisation(mo.getOrganisation()); mr.setRole(role); mr.setActif(true); mr.setDateDebut(LocalDate.now()); entityManager.persist(mr); LOG.infof( "MembreRole ORGADMIN auto-sync créé pour membre %s dans org %s", mo.getMembre() != null ? mo.getMembre().getId() : "?", mo.getOrganisation().getId()); }, () -> LOG.warnf( "Rôle ORGADMIN introuvable dans la table roles — " + "vérifier que V13__Seed_Standard_Roles.sql a été appliqué") ); } }