diff --git a/src/main/java/dev/lions/unionflow/server/service/SouscriptionService.java b/src/main/java/dev/lions/unionflow/server/service/SouscriptionService.java
index 7efb8f8..a56ff17 100644
--- a/src/main/java/dev/lions/unionflow/server/service/SouscriptionService.java
+++ b/src/main/java/dev/lions/unionflow/server/service/SouscriptionService.java
@@ -448,56 +448,68 @@ public class SouscriptionService {
* Si aucun lien membre-organisation n'existe, tente de créer le lien pour le
* caller courant (email JWT) avant d'activer.
*/
+ /**
+ * Active l'admin de l'organisation après paiement de la souscription.
+ *
+ *
Stratégie : identifier le membre qui a payé (via JWT) et le promouvoir
+ * ORGADMIN. Si le membre n'a pas de lien MembreOrganisation, le créer.
+ *
+ *
Cascades : promouvoirAdminOrganisation (DB) + sync Keycloak ADMIN_ORGANISATION.
+ */
private void activerAdminOrganisation(UUID organisationId) {
- List liens =
- membreOrganisationRepository.findAllByOrganisationId(organisationId);
+ // ── 1. Identifier le caller (le membre qui a payé) ─────────────────────
+ String email = securiteHelper.resolveEmail();
+ if (email == null) {
+ LOG.warnf("activerAdminOrganisation: impossible de résoudre l'email JWT pour org=%s", organisationId);
+ return;
+ }
- if (liens.isEmpty()) {
- LOG.warnf("activerAdminOrganisation: aucun lien membre-organisation trouvé pour org=%s — tentative de liaison via JWT", organisationId);
+ Membre caller = membreRepository.findByEmail(email).orElse(null);
+ if (caller == null) {
+ LOG.warnf("activerAdminOrganisation: aucun membre trouvé pour email=%s", email);
+ return;
+ }
- // Récupérer l'email du caller depuis le JWT
- String email = securiteHelper.resolveEmail();
- if (email == null) {
- LOG.warnf("activerAdminOrganisation: impossible de résoudre l'email JWT pour org=%s", organisationId);
- return;
- }
+ Organisation org = organisationRepo.findByIdOptional(organisationId).orElse(null);
+ if (org == null) {
+ LOG.warnf("activerAdminOrganisation: organisation introuvable org=%s", organisationId);
+ return;
+ }
- Membre caller = membreRepository.findByEmail(email).orElse(null);
- if (caller == null) {
- LOG.warnf("activerAdminOrganisation: aucun membre trouvé pour email=%s", email);
- return;
- }
+ LOG.infof("activerAdminOrganisation: caller=%s (%s) pour org=%s (%s)",
+ caller.getId(), email, organisationId, org.getNom());
- Organisation org = organisationRepo.findByIdOptional(organisationId).orElse(null);
- if (org == null) {
- LOG.warnf("activerAdminOrganisation: organisation introuvable org=%s", organisationId);
- return;
- }
+ // ── 2. S'assurer que le caller a un lien MembreOrganisation ────────────
+ var lienOpt = membreOrganisationRepository
+ .findByMembreIdAndOrganisationId(caller.getId(), organisationId);
- // Créer le lien MembreOrganisation à la volée
+ if (lienOpt.isEmpty()) {
+ LOG.infof("activerAdminOrganisation: pas de lien existant — création pour membre=%s org=%s", caller.getId(), organisationId);
membreService.lierMembreOrganisationEtIncrementerQuota(caller, organisationId, "ACTIF");
- LOG.infof("activerAdminOrganisation: lien créé à la volée pour membre=%s org=%s", caller.getId(), organisationId);
-
- // Recharger et activer
- liens = membreOrganisationRepository.findAllByOrganisationId(organisationId);
- }
-
- for (dev.lions.unionflow.server.entity.MembreOrganisation lien : liens) {
- Membre m = lien.getMembre();
- if (m != null && !"ACTIF".equals(m.getStatutCompte())) {
- // Promouvoir → statut ACTIF + rôle ORGADMIN en base
- membreService.promouvoirAdminOrganisation(m.getId());
- // Sync Keycloak : assigner ADMIN_ORGANISATION (non-bloquant)
- try {
- keycloakSyncService.promouvoirAdminOrganisationDansKeycloak(m.getId());
- } catch (Exception e) {
- LOG.warnf("Keycloak sync ORGADMIN échouée pour membre=%s (non-bloquant): %s", m.getId(), e.getMessage());
- }
- LOG.infof("Membre admin %s promu ORGADMIN pour organisation %s", m.getId(), organisationId);
- return;
+ } else {
+ // Activer le lien existant s'il est en attente
+ var lien = lienOpt.get();
+ if (lien.getStatutMembre() != dev.lions.unionflow.server.api.enums.membre.StatutMembre.ACTIF) {
+ lien.setStatutMembre(dev.lions.unionflow.server.api.enums.membre.StatutMembre.ACTIF);
+ LOG.infof("activerAdminOrganisation: lien existant activé (statut→ACTIF) pour membre=%s", caller.getId());
}
}
- LOG.infof("activerAdminOrganisation: tous les membres de org=%s sont déjà ACTIF", organisationId);
+
+ // ── 3. Promouvoir en ORGADMIN (DB + Keycloak) ──────────────────────────
+ try {
+ membreService.promouvoirAdminOrganisation(caller.getId());
+ LOG.infof("activerAdminOrganisation: membre %s promu ORGADMIN en DB", caller.getId());
+ } catch (Exception e) {
+ LOG.errorf("activerAdminOrganisation: échec promotion DB pour membre=%s : %s", caller.getId(), e.getMessage());
+ }
+
+ try {
+ keycloakSyncService.promouvoirAdminOrganisationDansKeycloak(caller.getId());
+ LOG.infof("activerAdminOrganisation: rôle Keycloak ADMIN_ORGANISATION assigné pour membre=%s", caller.getId());
+ } catch (Exception e) {
+ LOG.warnf("activerAdminOrganisation: sync Keycloak ORGADMIN échouée pour membre=%s (non-bloquant): %s",
+ caller.getId(), e.getMessage());
+ }
}
private void notifierSuperAdmins(SouscriptionOrganisation souscription) {