- Task #6: WebSocket /ws/dashboard + Kafka events (5 topics) * Backend: KafkaEventProducer, KafkaEventConsumer * Mobile: WebSocketService (reconnection, heartbeat, typed events) * DashboardBloc: Auto-refresh depuis WebSocket events - Finance Workflow: approbations + budgets (backend + mobile) * Backend: entities, services, resources, migrations Flyway V6 * Mobile: features finance_workflow complète avec BLoC - Corrections DI: interfaces IRepository partout * IProfileRepository, IOrganizationRepository, IMembreRepository * GetIt configuré avec @injectable - Spec-Kit: constitution + templates mis à jour * .specify/memory/constitution.md enrichie * Templates agent, plan, spec, tasks, checklist - Nettoyage: fichiers temporaires supprimés Signed-off-by: lions dev Team
12 KiB
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 ❌
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 ✅
/**
* 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
<h:panelGroup id="panelStatistiques" layout="block" styleClass="grid mb-3">
Après ✅ : KPI visibles uniquement pour ADMIN
<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
<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
<h:panelGroup id="panelActionsGroupees"
rendered="#{not empty membreListeBean.selectedMembres}">
Après ✅ : Actions groupées visibles uniquement pour ADMIN
<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
<p:column selectionMode="multiple" headerText="" />
Après ✅ : Checkbox visible uniquement pour ADMIN
<p:column selectionMode="multiple" headerText=""
rendered="#{menuBean.gestionMembresMenuVisible}" />
5. Actions DataTable (Lignes 223-258)
Action "Voir Profil" - TOUS ✅
<!-- 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 ✅
<!-- Éditer - ADMIN SEULEMENT -->
<p:button icon="pi pi-pencil" outcome="membreModifierPage" title="Modifier"
rendered="#{menuBean.gestionMembresMenuVisible}" />
Action "Contacter" - TOUS ✅
<!-- Contacter - TOUS -->
<p:commandButton icon="pi pi-envelope" title="Contacter" />
Action "Suspendre" - ADMIN SEULEMENT ✅
<!-- 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 ✅
<!-- 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 :
- Créer table
configuration_organisation
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
);
- Créer
ConfigurationService
@ApplicationScoped
public class ConfigurationService {
public boolean isAnnuaireMembresActive() {
// Lire depuis configuration_organisation
return config != null && config.isAnnuaireMembresActif();
}
}
- Modifier
MenuBean.isAnnuaireMembresVisible()
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;
}
- 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 :
<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
- Phase 1 : Menu "Annuaire des Membres" masqué pour MEMBRE_ACTIF
- Phase 2 : Page liste.xhtml conditionnée selon le rôle
- KPI statistiques masqués pour MEMBRE_ACTIF
- Actions header masquées pour MEMBRE_ACTIF
- Actions groupées masquées pour MEMBRE_ACTIF
- Colonne checkbox masquée pour MEMBRE_ACTIF
- 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
- Se connecter avec un compte MEMBRE_ACTIF (sans autre rôle)
- 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.)
- Accéder directement à
/pages/secure/membre/liste.xhtml(via URL) - 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
- Se connecter avec un compte SECRETAIRE
- Vérifier menu :
- "Annuaire des Membres" visible
- "Gestion des Membres" visible
- Accéder à
/pages/secure/membre/liste.xhtml - 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
- Se connecter avec un compte ADMIN_ORGANISATION
- 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)