# Changements UX - Menu et Pages par Rôle (Appliqués)

> **Date**: 2026-03-02
> **Système**: UnionFlow - Révision UX Menu et Accès par Rôle
> **Statut**: ✅ **Phase 1 et Phase 2 APPLIQUÉES**

---

## Changements Appliqués

### ✅ Phase 1 : Menu - Retrait MEMBRE_ACTIF de l'Annuaire

**Fichier modifié** : `MenuBean.java`

**Méthode** : `isAnnuaireMembresVisible()`

#### Avant ❌
```java
public boolean isAnnuaireMembresVisible() {
    return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "TRESORIER",
                     "RESPONSABLE_SOCIAL", "RESPONSABLE_EVENEMENTS", "RESPONSABLE_CREDIT",
                     "MEMBRE_BUREAU", "MEMBRE_ACTIF"); // ← PROBLÈME
}
```

#### Après ✅
```java
/**
 * Annuaire des Membres - Consultation de la liste (pas de modification)
 * Visible pour les responsables et bureau SEULEMENT (PAS pour MEMBRE_ACTIF)
 *
 * Raison métier: Un membre simple n'a généralement pas besoin de voir la liste complète
 * des autres membres. Cela peut poser des problèmes de:
 * - RGPD: Exposition non justifiée de données personnelles
 * - Sécurité: Risque de spam/phishing entre membres
 * - UX: Surcharge du menu pour un usage limité
 */
public boolean isAnnuaireMembresVisible() {
    return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "TRESORIER",
                     "RESPONSABLE_SOCIAL", "RESPONSABLE_EVENEMENTS", "RESPONSABLE_CREDIT",
                     "MEMBRE_BUREAU");
    // MEMBRE_ACTIF retiré intentionnellement pour raisons UX et RGPD
}
```

**Résultat** :
- ✅ Menu "Annuaire des Membres" **masqué** pour les utilisateurs avec rôle **MEMBRE_ACTIF**
- ✅ Menu visible uniquement pour SECRETAIRE, TRESORIER, RESPONSABLES, ADMIN

---

### ✅ Phase 2 : Page Liste Membres - Conditionnement par Rôle

**Fichier modifié** : `/pages/secure/membre/liste.xhtml`

#### 1. KPI Statistiques (Lignes 31-64)

**Avant** ❌ : KPI visibles pour **TOUS**
```xml
<h:panelGroup id="panelStatistiques" layout="block" styleClass="grid mb-3">
```

**Après** ✅ : KPI visibles uniquement pour **ADMIN**
```xml
<h:panelGroup id="panelStatistiques" layout="block" styleClass="grid mb-3"
              rendered="#{menuBean.gestionMembresMenuVisible}">
```

**KPI conditionnés** :
- Total Membres
- Membres Actifs
- Membres Inactifs/Suspendus
- Nouveaux Membres (30j)

---

#### 2. Actions Header (Lignes 21-24)

**Avant** ❌ : Boutons visibles pour **TOUS**

**Après** ✅ : Boutons visibles uniquement pour **ADMIN**
```xml
<p:button value="Nouveau Membre" icon="pi pi-user-plus"
          rendered="#{menuBean.gestionMembresMenuVisible}" />
<p:commandButton value="Import / Export" icon="pi pi-file-excel"
                 rendered="#{menuBean.gestionMembresMenuVisible}" />
```

**Actions conditionnées** :
- Nouveau Membre
- Import / Export

---

#### 3. Actions Groupées (Lignes 129-143)

**Avant** ❌ : Actions groupées visibles pour **TOUS** si sélection
```xml
<h:panelGroup id="panelActionsGroupees"
              rendered="#{not empty membreListeBean.selectedMembres}">
```

**Après** ✅ : Actions groupées visibles uniquement pour **ADMIN**
```xml
<h:panelGroup id="panelActionsGroupees"
              rendered="#{not empty membreListeBean.selectedMembres and menuBean.gestionMembresMenuVisible}">
```

**Actions conditionnées** :
- Rappel Cotisations Groupé
- Message Groupé
- Exporter Sélection

---

#### 4. Colonne Sélection (Ligne 166)

**Avant** ❌ : Checkbox visible pour **TOUS**
```xml
<p:column selectionMode="multiple" headerText="" />
```

**Après** ✅ : Checkbox visible uniquement pour **ADMIN**
```xml
<p:column selectionMode="multiple" headerText=""
          rendered="#{menuBean.gestionMembresMenuVisible}" />
```

---

#### 5. Actions DataTable (Lignes 223-258)

##### Action "Voir Profil" - TOUS ✅
```xml
<!-- Voir le profil - TOUS -->
<p:button icon="pi pi-user" outcome="membreProfilPage" title="Profil" />
```
**Pas de condition** : Tous les utilisateurs peuvent consulter un profil

##### Action "Éditer" - ADMIN SEULEMENT ✅
```xml
<!-- Éditer - ADMIN SEULEMENT -->
<p:button icon="pi pi-pencil" outcome="membreModifierPage" title="Modifier"
          rendered="#{menuBean.gestionMembresMenuVisible}" />
```

##### Action "Contacter" - TOUS ✅
```xml
<!-- Contacter - TOUS -->
<p:commandButton icon="pi pi-envelope" title="Contacter" />
```

##### Action "Suspendre" - ADMIN SEULEMENT ✅
```xml
<!-- Suspendre - ADMIN SEULEMENT (visible si actif) -->
<p:commandButton icon="pi pi-ban" title="Suspendre"
                 rendered="#{menuBean.gestionMembresMenuVisible and membre.statut == 'ACTIF'}" />
```

##### Action "Réactiver" - ADMIN SEULEMENT ✅
```xml
<!-- Réactiver - ADMIN SEULEMENT (visible si suspendu) -->
<p:commandButton icon="pi pi-replay" title="Réactiver"
                 rendered="#{menuBean.gestionMembresMenuVisible and membre.statut == 'SUSPENDU'}" />
```

---

## Résultat UX par Rôle

### Pour MEMBRE_ACTIF 👤

**Menu** :
- ❌ "Annuaire des Membres" → **MASQUÉ**
- ✅ Uniquement les menus personnels (Mes Finances, Événements, Aide Sociale, etc.)

**Page `/pages/secure/membre/liste.xhtml`** (si accessible directement par URL) :
- ❌ KPI statistiques → **MASQUÉS**
- ❌ Bouton "Nouveau Membre" → **MASQUÉ**
- ❌ Bouton "Import / Export" → **MASQUÉ**
- ❌ Actions groupées (Rappel, Message, Export) → **MASQUÉES**
- ❌ Colonne checkbox sélection → **MASQUÉE**
- ✅ Bouton "Voir Profil" → **VISIBLE**
- ❌ Bouton "Éditer" → **MASQUÉ**
- ✅ Bouton "Contacter" → **VISIBLE**
- ❌ Bouton "Suspendre/Réactiver" → **MASQUÉ**

**Résultat** : Page affichée en mode **lecture seule** (consultation profil + contact uniquement)

---

### Pour SECRETAIRE / ADMIN_ORGANISATION 🔐

**Menu** :
- ✅ "Annuaire des Membres" → **VISIBLE**
- ✅ "Gestion des Membres" → **VISIBLE**
- ✅ Tous les autres menus selon leur rôle

**Page `/pages/secure/membre/liste.xhtml`** :
- ✅ **TOUS les éléments visibles** (KPI, actions, boutons)
- ✅ Mode **administration complète**

---

## Principe Métier Respecté

### Question Fondamentale Adressée

> **"Pourquoi un membre d'une mutuelle devrait-il voir la liste des membres ou rechercher un membre ?"**

**Réponse** :
- ✅ Un **MEMBRE_ACTIF** n'a généralement **PAS besoin** de ces fonctions
- ✅ C'est le rôle du **SECRETAIRE** ou **ADMIN** de gérer les membres
- ✅ Évite les problèmes **RGPD** (exposition données personnelles)
- ✅ Simplifie le menu et améliore l'**UX**

### Arguments Métier

| Critère | MEMBRE_ACTIF | SECRETAIRE/ADMIN |
|---------|--------------|------------------|
| **Voir liste complète** | ❌ Non pertinent | ✅ Nécessaire |
| **Statistiques membres** | ❌ Non pertinent | ✅ Nécessaire |
| **Créer/Modifier membres** | ❌ Non autorisé | ✅ Nécessaire |
| **Actions groupées** | ❌ Non autorisé | ✅ Nécessaire |
| **Voir profil individuel** | ✅ Pertinent (lien social) | ✅ Pertinent |
| **Contacter un membre** | ✅ Pertinent (communication) | ✅ Pertinent |

---

## Travaux Restants

### Phase 3 : Configuration Optionnelle (À implémenter)

Si une organisation souhaite **activer l'annuaire** pour les MEMBRE_ACTIF :

1. Créer table `configuration_organisation`
```sql
CREATE TABLE configuration_organisation (
    id UUID PRIMARY KEY,
    organisation_id UUID REFERENCES organisation(id),
    annuaire_membres_actif BOOLEAN DEFAULT FALSE,
    annuaire_membres_champs_visibles TEXT[], -- ["nom", "prenom", "telephone"]
    annuaire_membres_recherche_avancee BOOLEAN DEFAULT FALSE
);
```

2. Créer `ConfigurationService`
```java
@ApplicationScoped
public class ConfigurationService {
    public boolean isAnnuaireMembresActive() {
        // Lire depuis configuration_organisation
        return config != null && config.isAnnuaireMembresActif();
    }
}
```

3. Modifier `MenuBean.isAnnuaireMembresVisible()`
```java
public boolean isAnnuaireMembresVisible() {
    // Toujours visible pour admins
    if (hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", ...)) {
        return true;
    }
    // Pour MEMBRE_ACTIF: vérifier config
    if (hasAnyRole("MEMBRE_ACTIF")) {
        return configService.isAnnuaireMembresActive(); // false par défaut
    }
    return false;
}
```

4. Créer page `/pages/secure/membre/annuaire.xhtml` (version simplifiée)
- Pas de KPI
- Pas d'actions administratives
- Filtres limités (nom/prénom seulement)
- Champs limités (pas d'email, pas d'adresse)

---

### Phase 4 : Révision Complète Menu (À implémenter)

Créer des menus séparés par rôle :
- `menu-membre-actif.xhtml` (~10 items)
- `menu-secretaire.xhtml` (~20 items)
- `menu-tresorier.xhtml` (~15 items)
- `menu-admin.xhtml` (~50+ items)

Charger dynamiquement dans `main-template.xhtml` :
```xml
<c:choose>
    <c:when test="#{menuBean.membreActif and not menuBean.anyAdminRole}">
        <ui:include src="/templates/components/layout/menu-membre-actif.xhtml" />
    </c:when>
    <c:when test="#{menuBean.secretaire or menuBean.adminOrganisation}">
        <ui:include src="/templates/components/layout/menu-admin.xhtml" />
    </c:when>
    <c:otherwise>
        <ui:include src="/templates/components/layout/menu.xhtml" />
    </c:otherwise>
</c:choose>
```

---

## Checklist de Validation

- [x] **Phase 1** : Menu "Annuaire des Membres" masqué pour MEMBRE_ACTIF
- [x] **Phase 2** : Page liste.xhtml conditionnée selon le rôle
  - [x] KPI statistiques masqués pour MEMBRE_ACTIF
  - [x] Actions header masquées pour MEMBRE_ACTIF
  - [x] Actions groupées masquées pour MEMBRE_ACTIF
  - [x] Colonne checkbox masquée pour MEMBRE_ACTIF
  - [x] Actions DataTable conditionnées (Éditer, Suspendre, Réactiver)
- [ ] **Phase 3** : Configuration optionnelle par organisation
- [ ] **Phase 4** : Menus séparés par rôle

---

## Tests à Effectuer

### Test 1 : Utilisateur MEMBRE_ACTIF

1. Se connecter avec un compte **MEMBRE_ACTIF** (sans autre rôle)
2. Vérifier menu :
   - [ ] "Annuaire des Membres" **n'apparaît PAS**
   - [ ] "Gestion des Membres" **n'apparaît PAS**
   - [ ] Menus personnels visibles (Mes Finances, Événements, etc.)
3. Accéder directement à `/pages/secure/membre/liste.xhtml` (via URL)
4. Vérifier page :
   - [ ] Pas de KPI statistiques en haut
   - [ ] Pas de bouton "Nouveau Membre"
   - [ ] Pas de bouton "Import / Export"
   - [ ] Pas de checkbox de sélection
   - [ ] Pas d'actions groupées
   - [ ] Bouton "Voir Profil" **visible**
   - [ ] Bouton "Éditer" **PAS visible**
   - [ ] Bouton "Contacter" **visible**
   - [ ] Bouton "Suspendre/Réactiver" **PAS visible**

### Test 2 : Utilisateur SECRETAIRE

1. Se connecter avec un compte **SECRETAIRE**
2. Vérifier menu :
   - [ ] "Annuaire des Membres" **visible**
   - [ ] "Gestion des Membres" **visible**
3. Accéder à `/pages/secure/membre/liste.xhtml`
4. Vérifier page :
   - [ ] KPI statistiques **visibles**
   - [ ] Bouton "Nouveau Membre" **visible**
   - [ ] Bouton "Import / Export" **visible**
   - [ ] Checkbox de sélection **visible**
   - [ ] Actions groupées **visibles** (si sélection)
   - [ ] **Toutes** les actions DataTable **visibles**

### Test 3 : Utilisateur ADMIN_ORGANISATION

1. Se connecter avec un compte **ADMIN_ORGANISATION**
2. Vérifier :
   - [ ] **Tous les éléments visibles** (comme SECRETAIRE)
   - [ ] Pas de restrictions

---

## Impact RGPD

**Avant** ❌ :
- Tous les membres voyaient la liste complète (nom, email, téléphone, adresse potentiellement)
- Exposition non justifiée de données personnelles

**Après** ✅ :
- Seuls les **responsables autorisés** voient la liste complète
- Conforme au principe de **minimisation** (RGPD Art. 5.1.c)
- Conforme au principe de **limitation des finalités** (RGPD Art. 5.1.b)

---

## Contact

**Documentation** :
- `docs/CHANGEMENTS_UX_MENU_APPLIQUES.md` (ce fichier)
- `docs/UX_MENU_PAR_ROLE.md` (recommandations complètes)
- `docs/KPI_DASHBOARD_PAR_ROLE.md` (matrice KPI)

**Code modifié** :
- `MenuBean.java` (ligne 135)
- `/pages/secure/membre/liste.xhtml` (lignes 32, 21-24, 130, 166, 234, 246, 255)
