================================================================================
AUDIT INDÉPENDANT — CODE SOURCE UNIONFLOW
(Base strictement sur le code source ; aucun fichier .md lu)
================================================================================

1. STRUCTURE ET DÉPENDANCES
--------------------------------------------------------------------------------
• Trois modules Maven identifiés : unionflow-server-api, unionflow-server-impl-quarkus,
  unionflow-client-quarkus-primefaces-freya. Pas de POM parent commun à la racine
  unionflow/ ; parent déclaré via parent-pom.xml dans unionflow-server-api.
• API : Java 17, Lombok, Bean Validation, Jackson, MicroProfile OpenAPI, JUnit 5,
  Mockito, AssertJ, Jacoco (seuils 1.00 sur lignes/instructions/méthodes/branches/classes).
• Impl : dépend de unionflow-server-api 1.0.0, lions-user-manager-server-api 1.0.0,
  Quarkus 3.15.1, Hibernate Panache, Flyway, OIDC, MapStruct 1.6.3, POI, OpenPDF.
  Jacoco : 1.00 lignes/instructions/méthodes, 0.30 branches. Checkstyle non exécuté
  (executions commentées dans API).
• Client : dépend de unionflow-server-api 1.0.0, Quarkus PrimeFaces, OIDC, REST Client.
  Pas de plugin Jacoco dans le client.

Risques : build multi-module non unifié (pas de reactor root) ; client sans couverture
automatique ; Checkstyle désactivé en API.


2. CONTRAT API / CLIENT – SERVEUR
--------------------------------------------------------------------------------
• Organisations : Le client (AssociationService) appelle GET /api/organisations?page=&size=
  et attend PagedResponse<OrganisationResponse>. Le serveur (OrganisationResource)
  renvoie PagedResponse<OrganisationSummaryResponse>. OrganisationSummaryResponse est un
  record (id, nom, nomCourt, typeOrganisation, typeOrganisationLibelle, statut, …) ;
  OrganisationResponse a plus de champs. Désérialisation possible mais type déclaré
  incorrect et champs manquants côté client = risque PropertyNotFoundException ou
  données incomplètes en vue.
• Membres : Client MembreService utilise GET /search et /search/advanced ; serveur expose
  GET /recherche (param q), GET /recherche-avancee (déprécié), POST /search/advanced.
  Incohérence de chemins pour recherche simple (client /search vs serveur /recherche).
• Types d’organisation : Client TypeOrganisationClientService appelle DELETE /{id}
  (méthode disable()) ; serveur TypeOrganisationReferenceResource fait bien DELETE
  (suppression réelle ou conditionnelle selon rôle). Alignement OK sur le chemin.
• DemandeAide : Client appelle GET /api/demandes-aide?page=&size= ; serveur renvoie
  List<DemandeAideResponse> (pas PagedResponse). Pagination côté serveur faite manuellement
  (subList). Contrat différent si le client attend un objet PagedResponse.


3. SÉCURITÉ (ANNOTATIONS)
--------------------------------------------------------------------------------
• HealthResource (/api/status) : aucune annotation @RolesAllowed ni @PermitAll.
  Comportement dépend de la config globale (souvent ouvert pour health checks).
• DemandeAideResource, PropositionAideResource : aucune annotation @RolesAllowed sur
  la ressource. Accès dépend de la politique par défaut (risque d’accès non restreint).
• RoleResource (/api/roles) : pas de @RolesAllowed.
• Incohérence des rôles : une partie des resources utilise des rôles en UPPER_CASE
  (ADMIN, MEMBRE, SUPER_ADMIN, USER, SUPER_ADMINISTRATEUR, TRESORIER, etc.), d’autres
  en lowercase (admin, admin_organisation, membre_actif, mutuelle_resp, vote_resp,
  tontine_resp, ong_resp, coop_resp, culte_resp, registre_resp). AnalyticsResource
  utilise MANAGER, MEMBER. Risque de refus ou d’accès inattendu selon le fournisseur
  de rôles (Keycloak vs custom).


4. BASE DE DONNÉES ET MIGRATIONS
--------------------------------------------------------------------------------
• Migrations Flyway : V1__UnionFlow_Complete_Schema.sql, V2__Entity_Schema_Alignment.sql
  (et README_CONSOLIDATION dans le même répertoire — non lu). Deux scripts principaux
  uniquement = consolidation déjà faite. Les tests désactivent Flyway
  (quarkus.flyway.enabled=false, migrate-at-start=false).


5. CLIENT JSF / PRIMEFACES
--------------------------------------------------------------------------------
• Convertisseur UUID : UuidConverter utilisé sur plusieurs pages (cotisations membre,
  adhesion, organisation-form, membre-form, import/export membre, comptabilité,
  documents). Un seul f:viewParam repéré avec converter="uuidConverter"
  (membre/cotisations.xhtml, id → membreCotisationBean.membreId). Les autres liaisons
  UUID sont surtout sur p:selectOneMenu. Toute vue qui lie une chaîne à un UUID sans
  converter peut provoquer une ELException (conversion String → UUID).
• Gestion des erreurs : ViewExpiredExceptionHandler enveloppe l’exception handler JSF,
  gère ViewExpiredException (redirection vers /, stockage redirectURL) et
  PropertyNotFoundException (log WARNING, redirection vers liste organisations,
  responseComplete). Typo dans le message de log : "already commited" (deux « m »).
  En cas de réponse déjà envoyée, le handler log en WARNING pour "already commited"
  / "already committed".
• Scopes des beans : mélange ViewScoped (listes, détail, formulaires ciblés) et
  SessionScoped (dashboard, demandes, rôles, adhesions, etc.). RolesBean en
  SessionScoped pour une liste de rôles = risque de données obsolètes si l’utilisateur
  garde l’onglet longtemps.


6. RESSOURCES REST SERVEUR – POINTS D’ATTENTION
--------------------------------------------------------------------------------
• OrganisationResource : GET sans path retourne PagedResponse<OrganisationSummaryResponse>
  avec paramètres page, size, recherche (optionnel). Client n’envoie pas « recherche ».
• CotisationResource : deux chemins pour des stats (/stats et /statistiques) ; les deux
  exposés pour compatibilité.
• TypeOrganisationReferenceResource : DELETE appelle supprimerPourSuperAdmin si
  SUPER_ADMIN/SUPER_ADMINISTRATEUR, sinon supprimer(id). Logique métier cohérente
  avec un rôle privilégié.
• Pas de @RolesAllowed sur DemandeAideResource, PropositionAideResource, RoleResource,
  HealthResource : à documenter ou à aligner avec la politique de sécurité globale.


7. QUALITÉ ET TESTS
--------------------------------------------------------------------------------
• API : Jacoco exige 1.00 sur tous les compteurs (dont branches). Très exigeant ;
  tout nouveau code non testé peut faire échouer le build.
• Impl : même politique 1.00 sauf branches à 0.30. Quarkus JUnit 5, RestAssured,
  quarkus-test-security, quarkus-jacoco.
• Client : pas de Jacoco configuré dans le POM ; pas de mesure de couverture côté
  client.
• Checkstyle (API) : exécutions en plugin commentées ; la qualité de style n’est pas
  appliquée au build.


8. DIVERS
--------------------------------------------------------------------------------
• Client TypeOrganisationClientService.disable() : nom de méthode « disable » alors que
  le serveur effectue une suppression (DELETE). Sémantique différente côté client.
• RestClientExceptionMapper (client) : mappe 4xx/5xx vers des exceptions dédiées ;
  pour 5xx le message est volontairement générique (pas d’exposition de détail).
• Doublon possible de DTO dashboard : MembreDashboardSyntheseResponse déplacé dans
  l’API (éviter split package) ; à confirmer qu’il n’existe plus dans l’impl.
• RolesBean (client) : supprimerRole() retire uniquement de la liste en mémoire ;
  AdminUserService n’expose pas de DELETE pour les rôles. Comportement « suppression »
  uniquement côté client.


9. SYNTHÈSE DES RISQUES ET RECOMMANDATIONS
--------------------------------------------------------------------------------
• Critique : Contrat liste organisations (PagedResponse<OrganisationResponse> vs
  PagedResponse<OrganisationSummaryResponse>). Aligner le type retourné ou le type
  attendu par le client (ex. adapter le client à OrganisationSummaryResponse ou
  faire renvoyer OrganisationResponse par le serveur).
• Important : Ressources sans @RolesAllowed (DemandeAide, PropositionAide, Role,
  Health). Définir une politique explicite (au moins pour DemandeAide, PropositionAide, Role).
• Important : Unification des noms de rôles (UPPER vs lowercase, MANAGER/MEMBER vs
  ADMIN/MEMBRE) en fonction du répertoire (Keycloak) pour éviter 403 ou accès trop larges.
• Moyen : Recherche membres — aligner chemins client (/search) et serveur (/recherche)
  ou documenter la différence et adapter le client.
• Moyen : Pagination demandes d’aide — retourner un PagedResponse si le client
  l’attend, ou documenter que la réponse est une List.
• Mineur : Typo "already commited" dans ViewExpiredExceptionHandler.
• Mineur : Activer Checkstyle ou supprimer la config si non souhaitée ; documenter
  l’absence de couverture côté client.

================================================================================
Fin de l’audit.
================================================================================
