Files
unionflow-server-api/unionflow/AUDIT_CODE_SOURCE.txt
dahoud e8ad874015 feat: WebSocket temps réel + Finance Workflow + corrections
- 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
2026-03-15 02:12:17 +00:00

146 lines
9.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

================================================================================
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 dorganisation : 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 daccè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.), dautres
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 daccè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 lexception 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 lutilisateur
garde longlet longtemps.
6. RESSOURCES REST SERVEUR POINTS DATTENTION
--------------------------------------------------------------------------------
• OrganisationResource : GET sans path retourne PagedResponse<OrganisationSummaryResponse>
avec paramètres page, size, recherche (optionnel). Client nenvoie 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 nest 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 dexposition de détail).
• Doublon possible de DTO dashboard : MembreDashboardSyntheseResponse déplacé dans
lAPI (éviter split package) ; à confirmer quil nexiste plus dans limpl.
• RolesBean (client) : supprimerRole() retire uniquement de la liste en mémoire ;
AdminUserService nexpose 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 daide — retourner un PagedResponse si le client
lattend, 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
labsence de couverture côté client.
================================================================================
Fin de laudit.
================================================================================