feat(sync): MembreRoleSyncService + count admins dynamique

- Nouveau MembreRoleSyncService.ensureOrgAdminRole : auto-crée un MembreRole ORGADMIN
  quand un user avec rôle Keycloak ADMIN_ORGANISATION se connecte sans entrée DB
  (couvre les comptes créés directement dans Keycloak).
- OrganisationContextFilter appelle syncService.ensureOrgAdminRole quand le rôle
  Keycloak est présent mais MembreRole absent (non bloquant sur erreur).
- MembreRoleRepository.countAdminsByOrganisationId : count strict (ORGADMIN + actif
  + dateDebut/dateFin valides) avec fallback sur codes alternatifs si strict=0.
- OrganisationService.convertToResponse : nombreAdministrateurs dynamique via
  MembreRoleRepository (remplace le champ Organisation jamais mis à jour).
This commit is contained in:
dahoud
2026-04-15 20:05:49 +00:00
parent e81c75b828
commit 78d8fd7cd8
4 changed files with 176 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.repository.MembreOrganisationRepository;
import dev.lions.unionflow.server.repository.MembreRepository;
import dev.lions.unionflow.server.repository.OrganisationRepository;
import dev.lions.unionflow.server.service.MembreRoleSyncService;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
@@ -54,6 +55,9 @@ public class OrganisationContextFilter implements ContainerRequestFilter {
@Inject
OrganisationRepository organisationRepository;
@Inject
MembreRoleSyncService membreRoleSyncService;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String orgIdHeader = requestContext.getHeaderString(HEADER_ACTIVE_ORG);
@@ -128,6 +132,18 @@ public class OrganisationContextFilter implements ContainerRequestFilter {
.build());
return;
}
// Sync rôle DB ↔ Keycloak : si l'utilisateur est admin dans Keycloak
// mais n'a pas encore de MembreRole ORGADMIN en base, le créer.
if (securityIdentity.getRoles().contains("ADMIN_ORGANISATION")) {
try {
membreRoleSyncService.ensureOrgAdminRole(membreOrg);
} catch (Exception e) {
// Non bloquant — on log et on continue
LOG.warnf("ensureOrgAdminRole: erreur non bloquante pour %s : %s",
email, e.getMessage());
}
}
}
}
}