# Révision UX - Menu et Pages par Rôle

> **Date**: 2026-03-02
> **Système**: UnionFlow - Navigation et Accès par Rôle
> **Principe**: **Chaque membre ne voit que ce qui est pertinent pour SON rôle**

---

## Problème Identifié

### État Actuel ❌

**Ligne 48-52 de menu.xhtml** : "Annuaire des Membres" est visible pour **TOUS** incluant **MEMBRE_ACTIF**

```xml
<!-- Annuaire des Membres (MEMBRE_ACTIF et plus - Consultation) -->
<p:submenu id="m_annuaire" label="Annuaire des Membres" icon="pi pi-users"
           rendered="#{menuBean.annuaireMembresVisible}">
    <p:menuitem id="m_liste_membres_lecture" value="Liste des Membres"
                icon="pi pi-list" outcome="/pages/secure/membre/liste" />
    <p:menuitem id="m_recherche_membres" value="Rechercher un Membre"
                icon="pi pi-search" outcome="/pages/secure/membre/recherche" />
</p:submenu>
```

**Problèmes UX** :
1. ❌ Un membre simple d'une mutuelle n'a **pas besoin** de voir la liste de tous les membres
2. ❌ Exposition de données personnelles (RGPD) sans raison métier
3. ❌ La page `/pages/secure/membre/liste.xhtml` affiche des **KPI administratifs** :
   - Total Membres
   - Membres Actifs/Inactifs
   - Nouveaux Membres (30j)
4. ❌ Actions administratives non pertinentes :
   - Nouveau Membre
   - Import/Export
   - Suspendre/Réactiver
   - Rappel Cotisations Groupé

---

## Question Métier Fondamentale

**Pour un MEMBRE_ACTIF d'une mutuelle, quels sont ses besoins réels ?**

✅ **Besoins légitimes** :
- SON dashboard personnel
- SES cotisations
- SON compte épargne
- SES inscriptions aux événements
- SES demandes d'aide sociale
- Consulter les événements publics (pour s'inscrire)
- Voir ses notifications personnelles
- Accéder à SON profil

❌ **Besoins NON légitimes** (rôles admin) :
- Voir la liste complète des membres
- Rechercher d'autres membres
- Voir les statistiques globales de l'organisation
- Créer/Modifier/Suspendre des membres
- Importer/Exporter des membres
- Envoyer des rappels de cotisations
- Voir la trésorerie globale

---

## Solution Recommandée

### 1. Révision du Menu par Rôle

#### A. Menu pour **MEMBRE_ACTIF** (Minimal)

```xml
<!-- MEMBRE_ACTIF - Menu Personnel Uniquement -->
<fr:menu widgetVar="FreyaMenuWidget">
    <!-- Dashboard Personnel -->
    <p:menuitem value="Mon Espace" icon="pi pi-home"
                outcome="/pages/secure/dashboard-membre" />

    <!-- Mes Finances -->
    <p:submenu label="Mes Finances" icon="pi pi-wallet">
        <p:menuitem value="Mes Cotisations" icon="pi pi-credit-card"
                    outcome="/pages/secure/membre/cotisations" />
        <p:menuitem value="Payer mes Cotisations" icon="pi pi-dollar"
                    outcome="/pages/secure/cotisation/paiement" />
        <p:menuitem value="Mon Épargne" icon="pi pi-money-bill"
                    outcome="/pages/secure/epargne/mon-compte" />
        <p:menuitem value="Mes Prêts" icon="pi pi-briefcase"
                    outcome="/pages/secure/credit/mes-prets"
                    rendered="#{config.moduleCredit}" />
    </p:submenu>

    <!-- Événements -->
    <p:submenu label="Événements" icon="pi pi-calendar">
        <p:menuitem value="Calendrier" icon="pi pi-calendar-plus"
                    outcome="/pages/secure/evenement/calendrier" />
        <p:menuitem value="Mes Inscriptions" icon="pi pi-list"
                    outcome="/pages/secure/evenement/mes-inscriptions" />
    </p:submenu>

    <!-- Aide Sociale -->
    <p:submenu label="Aide Sociale" icon="pi pi-heart">
        <p:menuitem value="Faire une Demande" icon="pi pi-plus"
                    outcome="/pages/secure/aide/demande" />
        <p:menuitem value="Mes Demandes" icon="pi pi-list"
                    outcome="/pages/secure/aide/mes-demandes" />
    </p:submenu>

    <!-- Communication -->
    <p:submenu label="Communication" icon="pi pi-envelope">
        <p:menuitem value="Mes Notifications" icon="pi pi-bell"
                    outcome="/pages/secure/communication/notifications" />
        <p:menuitem value="Annonces" icon="pi pi-megaphone"
                    outcome="/pages/secure/communication/annonces" />
    </p:submenu>

    <!-- Mon Profil -->
    <p:menuitem value="Mon Profil" icon="pi pi-user"
                outcome="/pages/secure/membre/mon-profil" />

    <!-- Aide -->
    <p:menuitem value="Aide" icon="pi pi-question-circle"
                outcome="/pages/secure/aide/support" />
</fr:menu>
```

**Total items** : ~10 items pertinents (vs ~50+ actuellement)

#### B. Menu pour **SECRETAIRE** (Gestion Administrative)

```xml
<!-- SECRETAIRE - Administration + Personnel -->
<fr:menu>
    <!-- Tous les items MEMBRE_ACTIF + -->

    <!-- Gestion des Membres -->
    <p:submenu label="Gestion des Membres" icon="pi pi-users-cog">
        <p:menuitem value="Nouvelle Inscription" outcome="/pages/secure/membre/inscription" />
        <p:menuitem value="Liste Complète" outcome="/pages/secure/membre/liste" />
        <p:menuitem value="Validation Inscriptions" outcome="/pages/secure/membre/validation" />
        <p:menuitem value="Import/Export" outcome="/pages/secure/membre/import" />
    </p:submenu>

    <!-- Gestion Événements -->
    <p:submenu label="Gestion Événements" icon="pi pi-calendar-clock">
        <p:menuitem value="Nouvel Événement" outcome="/pages/secure/evenement/creation" />
        <p:menuitem value="Planification" outcome="/pages/secure/evenement/planification" />
        <p:menuitem value="Gestion Participations" outcome="/pages/secure/evenement/participation" />
    </p:submenu>

    <!-- Communication -->
    <p:submenu label="Communication" icon="pi pi-megaphone">
        <p:menuitem value="Envoyer SMS/Email" outcome="/pages/secure/communication/envoi" />
        <p:menuitem value="Annonces Officielles" outcome="/pages/secure/communication/annonces-admin" />
    </p:submenu>
</fr:menu>
```

#### C. Menu pour **TRESORIER** (Gestion Financière)

```xml
<!-- TRESORIER - Finances + Personnel -->
<fr:menu>
    <!-- Tous les items MEMBRE_ACTIF + -->

    <!-- Gestion Financière -->
    <p:submenu label="Gestion Financière" icon="pi pi-dollar">
        <p:menuitem value="Trésorerie" outcome="/pages/secure/finance/tresorerie" />
        <p:menuitem value="Cotisations Globales" outcome="/pages/admin/cotisations/gestion" />
        <p:menuitem value="Comptabilité" outcome="/pages/secure/comptabilite/gestion" />
        <p:menuitem value="Relances Cotisations" outcome="/pages/secure/cotisation/relances" />
        <p:menuitem value="Rapports Financiers" outcome="/pages/secure/finance/rapports" />
    </p:submenu>

    <!-- Épargne et Crédit (si module actif) -->
    <p:submenu label="Épargne et Crédit" icon="pi pi-money-bill">
        <p:menuitem value="Demandes de Crédit" outcome="/pages/secure/credit/demandes" />
        <p:menuitem value="Suivi des Crédits" outcome="/pages/secure/credit/suivi" />
        <p:menuitem value="Remboursements" outcome="/pages/secure/credit/remboursements" />
    </p:submenu>
</fr:menu>
```

#### D. Menu pour **ADMIN_ORGANISATION** (Tout)

```xml
<!-- ADMIN_ORGANISATION - Tous les menus -->
<fr:menu>
    <!-- Dashboard Admin -->
    <p:menuitem value="Dashboard Admin" outcome="/pages/secure/dashboard" />

    <!-- Tous les menus de gestion -->
    <!-- + Tous les items personnels -->
</fr:menu>
```

---

### 2. Révision des Pages par Rôle

#### A. `/pages/secure/membre/liste.xhtml`

**État actuel** : Une seule page pour tous (admin + membres)

**Solution** : Conditionner l'affichage selon le rôle

```xml
<!-- KPI Statistiques - Visible uniquement pour SECRETAIRE, ADMIN -->
<h:panelGroup id="panelStatistiques" layout="block" styleClass="grid mb-3"
              rendered="#{menuBean.gestionMembresMenuVisible}">
    <div class="col-12 md:col-3">
        <ui:decorate template="/templates/components/cards/stat-card.xhtml">
            <ui:param name="value" value="#{membreListeBean.totalMembres}" />
            <ui:param name="label" value="Total Membres" />
        </ui:decorate>
    </div>
    <!-- Autres KPI... -->
</h:panelGroup>

<!-- Actions Admin - Visible uniquement pour SECRETAIRE, ADMIN -->
<ui:define name="actions">
    <p:button value="Nouveau Membre" icon="pi pi-user-plus"
              outcome="membreInscriptionPage"
              rendered="#{menuBean.gestionMembresMenuVisible}"
              styleClass="ui-button-success mr-2" />
    <p:commandButton value="Import / Export" icon="pi pi-file-excel"
                     rendered="#{menuBean.gestionMembresMenuVisible}"
                     onclick="PF('dlgImportExport').show();" />
</ui:define>

<!-- Actions en DataTable - Visible uniquement pour SECRETAIRE, ADMIN -->
<ui:define name="actions">
    <!-- Voir le profil - TOUS -->
    <p:button icon="pi pi-user" outcome="membreProfilPage" title="Profil" />

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

    <!-- Contacter - TOUS -->
    <p:commandButton icon="pi pi-envelope" title="Contacter" />

    <!-- Suspendre - ADMIN SEULEMENT -->
    <p:commandButton icon="pi pi-ban" title="Suspendre"
                     rendered="#{menuBean.gestionMembresMenuVisible and membre.statut == 'ACTIF'}" />
</ui:define>
```

**Alternative** : Créer 2 pages séparées

- `/pages/secure/membre/liste.xhtml` → Admin seulement (avec KPI et actions)
- `/pages/secure/membre/annuaire.xhtml` → Tous (lecture seule, pas de KPI)

#### B. `/pages/secure/dashboard.xhtml` vs `/pages/secure/dashboard-membre.xhtml`

**Actuellement** : Bien séparés ✅

- `dashboard.xhtml` → ADMIN, RESPONSABLES (KPI globaux)
- `dashboard-membre.xhtml` → MEMBRE_ACTIF (données personnelles)

**À conserver** tel quel.

---

### 3. Modification de MenuBean.java

#### Réviser `isAnnuaireMembresVisible()`

**Avant** (ligne 135-139) :
```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** (Option 1 - Restrictif) :
```java
/**
 * Annuaire des Membres - Consultation limitée
 * Visible pour les responsables et bureau SEULEMENT (pas MEMBRE_ACTIF)
 *
 * Raison métier: Un membre simple n'a pas besoin de voir la liste complète
 * des autres membres (RGPD, pertinence métier limitée)
 */
public boolean isAnnuaireMembresVisible() {
    return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "TRESORIER",
                     "RESPONSABLE_SOCIAL", "RESPONSABLE_EVENEMENTS", "RESPONSABLE_CREDIT",
                     "MEMBRE_BUREAU");
    // MEMBRE_ACTIF retiré intentionnellement
}
```

**Après** (Option 2 - Configurable par Organisation) :
```java
@Inject
ConfigurationService configService; // Service qui lit config de l'organisation

/**
 * Annuaire des Membres - Consultation limitée
 * Visible selon configuration de l'organisation
 */
public boolean isAnnuaireMembresVisible() {
    // Toujours visible pour les admins
    if (hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "TRESORIER",
                  "RESPONSABLE_SOCIAL", "RESPONSABLE_EVENEMENTS", "RESPONSABLE_CREDIT",
                  "MEMBRE_BUREAU")) {
        return true;
    }

    // Pour MEMBRE_ACTIF: vérifier si l'organisation autorise l'annuaire
    if (hasAnyRole("MEMBRE_ACTIF")) {
        return configService.isAnnuaireMembresActive(); // false par défaut
    }

    return false;
}
```

---

## Cas d'Usage Métier - Annuaire pour MEMBRE_ACTIF ?

### ✅ Arguments POUR (lien social)

1. **Faciliter la communication** entre membres
2. **Créer du lien social** dans la mutuelle
3. **Trouver des contacts** pour covoiturage aux événements
4. **Identifier des compétences** (ex: trouver un plombier membre)

### ❌ Arguments CONTRE (protection données)

1. **RGPD** : Exposition non justifiée de données personnelles
2. **Sécurité** : Risque de phishing/spam entre membres
3. **Pertinence limitée** : Un membre n'a généralement pas besoin de la liste complète
4. **Surcharge cognitive** : Menu trop chargé pour un usage quotidien limité

### 💡 Recommandation

**Option privilégiée** : **Désactiver par défaut**, rendre **configurable par organisation**

```java
// Configuration dans table `configuration_organisation`
{
    "annuaire_membres_actif": false, // Par défaut : désactivé
    "annuaire_membres_champs_visibles": ["nom", "prenom", "telephone"], // Pas email
    "annuaire_membres_recherche_avancee": false // Recherche simple seulement
}
```

Si l'organisation **active** l'annuaire pour MEMBRE_ACTIF :
- ✅ Afficher une **version limitée** (pas de KPI, pas d'actions admin)
- ✅ Masquer certains champs sensibles (email optionnel, pas d'adresse)
- ✅ Limiter la recherche (nom/prénom seulement, pas de filtres avancés)

---

## Plan d'Action

### Phase 1 : Menu ✅ (Immédiat)

- [ ] Modifier `MenuBean.isAnnuaireMembresVisible()` pour exclure `MEMBRE_ACTIF`
- [ ] Tester que le menu "Annuaire des Membres" n'apparaît plus pour MEMBRE_ACTIF
- [ ] Vérifier que les autres menus sont bien visibles selon les rôles

### Phase 2 : Pages Conditionnelles 🔧 (Court terme)

- [ ] Ajouter `rendered="#{menuBean.gestionMembresMenuVisible}"` sur les KPI de `liste.xhtml`
- [ ] Ajouter `rendered="#{menuBean.gestionMembresMenuVisible}"` sur les actions admin
- [ ] Conditionner les actions du DataTable (Éditer, Suspendre) selon le rôle
- [ ] Tester avec un utilisateur MEMBRE_ACTIF : pas de KPI, pas d'actions admin

### Phase 3 : Configuration Optionnelle 🚀 (Moyen terme)

- [ ] Créer table `configuration_organisation` avec champ `annuaire_membres_actif`
- [ ] Créer `ConfigurationService.isAnnuaireMembresActive()`
- [ ] Modifier `MenuBean.isAnnuaireMembresVisible()` pour utiliser la config
- [ ] Créer page admin `/pages/admin/configuration/annuaire.xhtml` pour activer/désactiver
- [ ] Si activé : créer page `/pages/secure/membre/annuaire.xhtml` (version simplifiée)

### Phase 4 : Révision Complète Menu 📋 (Long terme)

- [ ] Créer des fichiers menu 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 le bon menu selon le rôle dans `main-template.xhtml`
- [ ] Simplifier `MenuBean` en supprimant les méthodes deprecated

---

## Checklist de Validation UX

Avant de déployer un menu ou une page, vérifier :

- [ ] **Pertinence métier** : L'utilisateur a-t-il besoin de cette fonction pour SON rôle ?
- [ ] **Moindre privilège** : La fonction n'expose-t-elle que les données nécessaires ?
- [ ] **Clarté** : L'intitulé du menu est-il explicite ? ("Mes Cotisations" vs "Cotisations")
- [ ] **Cohérence** : Les fonctions "MES" vs "GESTION" sont-elles bien séparées ?
- [ ] **Simplicité** : Le menu n'est-il pas surchargé ? (max 10-15 items pour MEMBRE_ACTIF)

---

## Contact

**Documentation** :
- `docs/UX_MENU_PAR_ROLE.md` (ce fichier)
- `docs/KPI_DASHBOARD_PAR_ROLE.md` (matrice KPI)
- `docs/PERMISSIONS_MATRIX.md` (permissions pages)

**Code** :
- `MenuBean.java` - Logique de visibilité
- `menu.xhtml` - Structure du menu
- `liste.xhtml` - Page à conditionner
