Files
unionflow-mobile-apps/DIAGRAMME_CLASSES_UNIONFLOW.md
dahoud d8529cedd3 docs: Ajout diagramme de classes complet UnionFlow
Documentation exhaustive de l'architecture UnionFlow:
- 9 entités JPA avec relations
- 10+ repositories spécialisés
- 15+ DTOs serveur et client
- 10+ services métier
- 15+ resources REST
- 30+ beans JSF
- 10+ enums
- Diagrammes de relations
- Points d'amélioration identifiés

Document généré après lecture intégrale de tous les fichiers Java.
2025-11-29 23:51:27 +00:00

1980 lines
53 KiB
Markdown

# Diagramme de Classes - UnionFlow
## Vue d'ensemble
UnionFlow est une application de gestion d'organisations (Lions Clubs, Associations, Coopératives, etc.) avec gestion des membres, cotisations, événements et système de solidarité.
**Architecture modulaire :**
- `unionflow-server-api` : Contrats API (DTOs, Enums, Interfaces)
- `unionflow-server-impl-quarkus` : Implémentation serveur (Entités JPA, Services, Resources REST)
- `unionflow-client-quarkus-primefaces-freya` : Client web JSF/PrimeFaces
---
## 1. ENTITÉS JPA (Server Implementation)
### 1.1 BaseEntity (Classe abstraite)
```java
@MappedSuperclass
public abstract class BaseEntity {
- UUID id (PK, @GeneratedValue UUID)
- LocalDateTime dateCreation
- LocalDateTime dateModification
- String creePar
- String modifiePar
- Long version (@Version)
- Boolean actif
+ onCreate() @PrePersist
+ onUpdate() @PreUpdate
}
```
**Relations :** Toutes les entités héritent de `BaseEntity`
---
### 1.2 Membre
```java
@Entity
@Table(name = "membres")
public class Membre extends BaseEntity {
- String numeroMembre (unique, @NotBlank)
- String prenom (@NotBlank)
- String nom (@NotBlank)
- String email (unique, @Email, @NotBlank)
- String motDePasse
- String telephone
- LocalDate dateNaissance (@NotNull)
- LocalDate dateAdhesion (@NotNull)
- String roles
// Relations
- Organisation organisation (@ManyToOne, LAZY)
+ getNomComplet(): String
+ isMajeur(): boolean
+ getAge(): int
}
```
**Relations :**
- `@ManyToOne``Organisation` (membre appartient à une organisation)
---
### 1.3 Organisation
```java
@Entity
@Table(name = "organisations")
public class Organisation extends BaseEntity {
- String nom (@NotBlank)
- String nomCourt
- String typeOrganisation (@NotBlank)
- String statut (@NotBlank)
- String description
- LocalDate dateFondation
- String numeroEnregistrement (unique)
// Contact
- String email (unique, @Email, @NotBlank)
- String telephone
- String telephoneSecondaire
- String emailSecondaire
// Adresse
- String adresse
- String ville
- String codePostal
- String region
- String pays
- BigDecimal latitude
- BigDecimal longitude
// Web
- String siteWeb
- String logo
- String reseauxSociaux
// Hiérarchie
- UUID organisationParenteId
- Integer niveauHierarchique
// Statistiques
- Integer nombreMembres
- Integer nombreAdministrateurs
// Finances
- BigDecimal budgetAnnuel
- String devise
- Boolean cotisationObligatoire
- BigDecimal montantCotisationAnnuelle
// Compléments
- String objectifs
- String activitesPrincipales
- String certifications
- String partenaires
- String notes
- Boolean organisationPublique
- Boolean accepteNouveauxMembres
// Relations
- List<Membre> membres (@OneToMany, mappedBy="organisation", LAZY)
+ getNomComplet(): String
+ getAncienneteAnnees(): int
+ isRecente(): boolean
+ isActive(): boolean
+ ajouterMembre()
+ retirerMembre()
+ activer(String utilisateur)
+ suspendre(String utilisateur)
+ dissoudre(String utilisateur)
}
```
**Relations :**
- `@OneToMany``Membre` (une organisation a plusieurs membres)
- Auto-référence via `organisationParenteId` (hiérarchie)
---
### 1.4 TypeOrganisationEntity
```java
@Entity
@Table(name = "uf_type_organisation")
public class TypeOrganisationEntity extends BaseEntity {
- String code (unique, @NotBlank)
- String libelle (@NotBlank)
- String description
- Integer ordreAffichage
}
```
**Relations :** Aucune (entité de référence)
---
### 1.5 Cotisation
```java
@Entity
@Table(name = "cotisations")
public class Cotisation extends BaseEntity {
- String numeroReference (unique, @NotBlank)
- Membre membre (@ManyToOne, @NotNull)
- String typeCotisation (@NotBlank)
- BigDecimal montantDu (@NotNull, @DecimalMin(0))
- BigDecimal montantPaye (@DecimalMin(0))
- String codeDevise (@NotBlank, @Pattern("^[A-Z]{3}$"))
- String statut (@NotBlank, @Pattern)
- LocalDate dateEcheance (@NotNull)
- LocalDateTime datePaiement
- String description
- String periode
- Integer annee (@NotNull, @Min(2020), @Max(2100))
- Integer mois (@Min(1), @Max(12))
- String observations
- Boolean recurrente
- Integer nombreRappels
- LocalDateTime dateDernierRappel
- UUID valideParId
- String nomValidateur
- LocalDateTime dateValidation
- String methodePaiement
- String referencePaiement
+ getMontantRestant(): BigDecimal
+ isEntierementPayee(): boolean
+ isEnRetard(): boolean
+ genererNumeroReference(): String (static)
}
```
**Relations :**
- `@ManyToOne``Membre` (une cotisation appartient à un membre)
---
### 1.6 Adhesion
```java
@Entity
@Table(name = "adhesions")
public class Adhesion extends BaseEntity {
- String numeroReference (unique, @NotBlank)
- Membre membre (@ManyToOne, @NotNull)
- Organisation organisation (@ManyToOne, @NotNull)
- LocalDate dateDemande (@NotNull)
- BigDecimal fraisAdhesion (@NotNull, @DecimalMin(0))
- BigDecimal montantPaye (@DecimalMin(0))
- String codeDevise (@NotBlank, @Pattern("^[A-Z]{3}$"))
- String statut (@NotBlank, @Pattern)
- LocalDate dateApprobation
- LocalDateTime datePaiement
- String methodePaiement
- String referencePaiement
- String motifRejet
- String observations
- String approuvePar
- LocalDate dateValidation
+ isPayeeIntegralement(): boolean
+ isEnAttentePaiement(): boolean
+ getMontantRestant(): BigDecimal
}
```
**Relations :**
- `@ManyToOne``Membre`
- `@ManyToOne``Organisation`
---
### 1.7 Evenement
```java
@Entity
@Table(name = "evenements")
public class Evenement extends BaseEntity {
- String titre (@NotBlank, @Size(3-200))
- String description (@Size(max=2000))
- LocalDateTime dateDebut (@NotNull)
- LocalDateTime dateFin
- String lieu (@Size(max=500))
- String adresse (@Size(max=1000))
- TypeEvenement typeEvenement (@Enumerated)
- StatutEvenement statut (@Enumerated)
- Integer capaciteMax (@Min(0))
- BigDecimal prix (@DecimalMin("0.00"))
- Boolean inscriptionRequise
- LocalDateTime dateLimiteInscription
- String instructionsParticulieres
- String contactOrganisateur
- String materielRequis
- Boolean visiblePublic
- Boolean actif
// Relations
- Organisation organisation (@ManyToOne, LAZY)
- Membre organisateur (@ManyToOne, LAZY)
- List<InscriptionEvenement> inscriptions (@OneToMany, mappedBy="evenement", LAZY)
enum TypeEvenement { ASSEMBLEE_GENERALE, REUNION, FORMATION, ... }
enum StatutEvenement { PLANIFIE, CONFIRME, EN_COURS, TERMINE, ANNULE, REPORTE }
+ isOuvertAuxInscriptions(): boolean
+ getNombreInscrits(): int
+ isComplet(): boolean
+ isEnCours(): boolean
+ isTermine(): boolean
+ getDureeEnHeures(): Long
+ getPlacesRestantes(): Integer
+ isMemberInscrit(UUID membreId): boolean
+ getTauxRemplissage(): Double
}
```
**Relations :**
- `@ManyToOne``Organisation`
- `@ManyToOne``Membre` (organisateur)
- `@OneToMany``InscriptionEvenement`
---
### 1.8 InscriptionEvenement
```java
@Entity
@Table(name = "inscriptions_evenement")
public class InscriptionEvenement extends BaseEntity {
- Membre membre (@ManyToOne, @NotNull)
- Evenement evenement (@ManyToOne, @NotNull)
- LocalDateTime dateInscription
- StatutInscription statut (@Enumerated)
- String commentaire
enum StatutInscription { CONFIRMEE, EN_ATTENTE, ANNULEE, REFUSEE }
+ isConfirmee(): boolean
+ isEnAttente(): boolean
+ isAnnulee(): boolean
+ confirmer()
+ annuler(String commentaire)
+ mettreEnAttente(String commentaire)
+ refuser(String commentaire)
}
```
**Relations :**
- `@ManyToOne``Membre`
- `@ManyToOne``Evenement`
---
### 1.9 DemandeAide
```java
@Entity
@Table(name = "demandes_aide")
public class DemandeAide extends BaseEntity {
- String titre (@NotBlank)
- String description (@NotBlank, TEXT)
- TypeAide typeAide (@Enumerated, @NotNull)
- StatutAide statut (@Enumerated, @NotNull)
- BigDecimal montantDemande
- BigDecimal montantApprouve
- LocalDateTime dateDemande
- LocalDateTime dateEvaluation
- LocalDateTime dateVersement
- Membre demandeur (@ManyToOne, @NotNull)
- Membre evaluateur (@ManyToOne)
- Organisation organisation (@ManyToOne, @NotNull)
- String justification (TEXT)
- String commentaireEvaluation (TEXT)
- Boolean urgence
- String documentsFournis
+ isEnAttente(): boolean
+ isApprouvee(): boolean
+ isRejetee(): boolean
+ isUrgente(): boolean
+ getPourcentageApprobation(): BigDecimal
}
```
**Relations :**
- `@ManyToOne``Membre` (demandeur)
- `@ManyToOne``Membre` (evaluateur)
- `@ManyToOne``Organisation`
---
### 1.10 AuditLog
```java
@Entity
@Table(name = "audit_logs")
public class AuditLog extends BaseEntity {
- String typeAction
- String severite
- String utilisateur
- String role
- String module
- String description
- String details (TEXT)
- String ipAddress
- String userAgent
- String sessionId
- LocalDateTime dateHeure
- String donneesAvant (TEXT)
- String donneesApres (TEXT)
- String entiteId
- String entiteType
}
```
**Relations :** Aucune (entité de log)
---
## 2. REPOSITORIES (Server Implementation)
### 2.1 BaseRepository<T>
```java
public abstract class BaseRepository<T extends BaseEntity> {
@PersistenceContext
protected EntityManager entityManager;
protected final Class<T> entityClass;
+ findById(UUID id): T
+ findByIdOptional(UUID id): Optional<T>
+ persist(T entity): void @Transactional
+ update(T entity): T @Transactional
+ delete(T entity): void @Transactional
+ deleteById(UUID id): boolean @Transactional
+ listAll(): List<T>
+ count(): long
+ existsById(UUID id): boolean
+ getEntityManager(): EntityManager
}
```
**Relations :**
- Générique sur `BaseEntity`
- Utilisé par tous les repositories
---
### 2.2 MembreRepository
```java
@ApplicationScoped
public class MembreRepository extends BaseRepository<Membre> {
+ findByEmail(String email): Optional<Membre>
+ findByNumeroMembre(String numero): Optional<Membre>
+ findAllActifs(): List<Membre>
+ countActifs(): long
+ findByNomOrPrenom(String recherche): List<Membre>
+ findAllActifs(Page page, Sort sort): List<Membre>
+ findByNomOrPrenom(String recherche, Page page, Sort sort): List<Membre>
+ countNouveauxMembres(LocalDate depuis): long
+ findByStatut(boolean actif, Page page, Sort sort): List<Membre>
+ findByTrancheAge(int ageMin, int ageMax, Page page, Sort sort): List<Membre>
+ rechercheAvancee(...): List<Membre>
+ countMembresActifs(UUID organisationId, LocalDateTime debut, LocalDateTime fin): Long
+ countMembresInactifs(UUID organisationId, LocalDateTime debut, LocalDateTime fin): Long
+ calculerMoyenneAge(UUID organisationId, LocalDateTime debut, LocalDateTime fin): Double
}
```
---
### 2.3 OrganisationRepository
```java
@ApplicationScoped
public class OrganisationRepository extends BaseRepository<Organisation> {
+ findByEmail(String email): Optional<Organisation>
+ findByNom(String nom): Optional<Organisation>
+ findByNumeroEnregistrement(String numero): Optional<Organisation>
+ findAllActives(): List<Organisation>
+ findAllActives(Page page, Sort sort): List<Organisation>
+ countActives(): long
+ findByStatut(String statut, Page page, Sort sort): List<Organisation>
+ findByType(String typeOrganisation, Page page, Sort sort): List<Organisation>
+ findByVille(String ville, Page page, Sort sort): List<Organisation>
+ findByPays(String pays, Page page, Sort sort): List<Organisation>
+ findByRegion(String region, Page page, Sort sort): List<Organisation>
+ findByOrganisationParente(UUID parenteId, Page page, Sort sort): List<Organisation>
+ findOrganisationsRacines(Page page, Sort sort): List<Organisation>
+ findByNomOrNomCourt(String recherche, Page page, Sort sort): List<Organisation>
+ rechercheAvancee(...): List<Organisation>
+ countNouvellesOrganisations(LocalDate depuis): long
+ findOrganisationsPubliques(Page page, Sort sort): List<Organisation>
+ findOrganisationsOuvertes(Page page, Sort sort): List<Organisation>
+ countByStatut(String statut): long
+ countByType(String typeOrganisation): long
}
```
---
### 2.4 Autres Repositories
- `TypeOrganisationRepository extends BaseRepository<TypeOrganisationEntity>`
- `CotisationRepository extends BaseRepository<Cotisation>`
- `AdhesionRepository extends BaseRepository<Adhesion>`
- `EvenementRepository extends BaseRepository<Evenement>`
- `DemandeAideRepository extends BaseRepository<DemandeAide>`
- `AuditLogRepository extends BaseRepository<AuditLog>`
---
## 3. DTOs SERVEUR (Server API)
### 3.1 BaseDTO (Classe abstraite)
```java
public abstract class BaseDTO implements Serializable {
- UUID id
- LocalDateTime dateCreation (@JsonFormat)
- LocalDateTime dateModification (@JsonFormat)
- String creePar
- String modifiePar
- Long version
- Boolean actif
+ marquerCommeNouveau(String utilisateur): void
+ marquerCommeModifie(String utilisateur): void
+ desactiver(String utilisateur): void
+ reactiver(String utilisateur): void
+ isNouveau(): boolean
+ isActif(): boolean
}
```
**Relations :** Tous les DTOs héritent de `BaseDTO`
---
### 3.2 MembreDTO
```java
public class MembreDTO extends BaseDTO {
- String numeroMembre (@Size(max=50))
- String nom (@NotBlank, @Size(2-50), @Pattern)
- String prenom (@NotBlank, @Size(2-50), @Pattern)
- String email (@NotBlank, @Email, @Size(max=100))
- String telephone (@Size(max=20))
- LocalDate dateNaissance (@Past)
- String adresse (@Size(max=200))
- String profession (@Size(max=100))
- String statutMatrimonial (@Size(max=20))
- String nationalite (@Size(max=50))
- String numeroIdentite (@Size(max=50))
- String typeIdentite (@Size(max=20))
- StatutMembre statut (@NotNull)
- UUID associationId (@NotNull)
- String associationNom
- LocalDate dateAdhesion
- String region (@Size(max=50))
- String ville (@Size(max=50))
- String quartier (@Size(max=50))
- String role (@Size(max=50))
- Boolean membreBureau
- Boolean responsable
- String photoUrl (@Size(max=255))
+ getStatutLibelle(): String
+ sontDonneesValides(): boolean
}
```
---
### 3.3 OrganisationDTO
```java
public class OrganisationDTO extends BaseDTO {
- String nom (@NotBlank, @Size)
- String nomCourt (@Size(max=50))
- TypeOrganisation typeOrganisation (@NotNull)
- StatutOrganisation statut (@NotNull)
- String description (@Size(max=2000))
- LocalDate dateFondation
- String numeroEnregistrement (@Size(max=100))
- String adresse (@Size(max=500))
- String ville (@Size(max=100))
- String region (@Size(max=100))
- String pays (@Size(max=100))
- String codePostal (@Pattern)
- BigDecimal latitude (@DecimalMin(-90), @DecimalMax(90))
- BigDecimal longitude (@DecimalMin(-180), @DecimalMax(180))
- String telephone (@Pattern)
- String telephoneSecondaire (@Pattern)
- String email (@Email, @Size(max=200))
- String emailSecondaire (@Email, @Size(max=200))
- String siteWeb (@Pattern, @Size(max=500))
- String logo (@Size(max=500))
- UUID organisationParenteId
- String nomOrganisationParente
- Integer niveauHierarchique
- Integer nombreMembres
- Integer nombreAdministrateurs
- BigDecimal budgetAnnuel (@DecimalMin(0), @Digits)
- String devise (@Pattern("^[A-Z]{3}$"))
- String objectifs (@Size(max=2000))
- String activitesPrincipales (@Size(max=2000))
- String reseauxSociaux (@Size(max=1000))
- String certifications (@Size(max=500))
- String partenaires (@Size(max=1000))
- String notes (@Size(max=1000))
- Boolean organisationPublique
- Boolean accepteNouveauxMembres
- Boolean cotisationObligatoire
- BigDecimal montantCotisationAnnuelle (@DecimalMin(0), @Digits)
+ estActive(): boolean
+ estInactive(): boolean
+ estSuspendue(): boolean
+ estEnCreation(): boolean
+ estDissoute(): boolean
+ getAncienneteAnnees(): int
+ getAncienneteMois(): int
+ possedGeolocalisation(): boolean
+ estOrganisationRacine(): boolean
+ possedeSousOrganisations(): boolean
+ getNomAffichage(): String
+ getAdresseComplete(): String
+ getRatioAdministrateurs(): double
+ hasBudget(): boolean
+ activer(String utilisateur): void
+ suspendre(String utilisateur): void
+ dissoudre(String utilisateur): void
+ desactiver(String utilisateur): void
+ mettreAJourNombreMembres(int nouveauNombre, String utilisateur): void
+ ajouterMembre(String utilisateur): void
+ retirerMembre(String utilisateur): void
}
```
---
### 3.4 TypeOrganisationDTO
```java
public class TypeOrganisationDTO extends BaseDTO {
- String code (@NotBlank, @Size(max=50))
- String libelle (@NotBlank, @Size(max=150))
- String description (@Size(max=500))
- Integer ordreAffichage
- Boolean actif
}
```
---
### 3.5 CotisationDTO
```java
public class CotisationDTO extends BaseDTO {
- String numeroReference (@NotBlank, @Size(max=50))
- UUID membreId (@NotNull)
- String numeroMembre
- String nomMembre
- UUID associationId (@NotNull)
- String nomAssociation
- String typeCotisation (@NotNull, @Pattern)
- String libelle (@NotBlank, @Size(max=100))
- String description (@Size(max=500))
- BigDecimal montantDu (@NotNull, @DecimalMin(0, inclusive=false))
- BigDecimal montantPaye (@DecimalMin(0))
- String codeDevise (@NotBlank, @Size(3))
- String statut (@NotNull, @Pattern)
- LocalDate dateEcheance (@NotNull)
- LocalDateTime datePaiement
- String methodePaiement (@Pattern)
- String referencePaiement (@Size(max=100))
- String periode (@Size(max=50))
- Integer annee (@Min(2020), @Max(2050))
- Integer mois (@Min(1), @Max(12))
- String observations (@Size(max=500))
- Boolean recurrente
- Integer nombreRappels (@Min(0))
- LocalDateTime dateDernierRappel
- UUID validePar
- String nomValidateur
+ isPayeeIntegralement(): boolean
+ isEnRetard(): boolean
+ getMontantRestant(): BigDecimal
+ getPourcentagePaiement(): int
+ getJoursRetard(): long
+ getTypeCotisationLibelle(): String
+ getStatutLibelle(): String
+ getMethodePaiementLibelle(): String
+ mettreAJourStatut(): void
+ marquerCommePaye(BigDecimal montant, String methode, String reference): void
}
```
---
### 3.6 AdhesionDTO
```java
public class AdhesionDTO extends BaseDTO {
- String numeroReference (@NotBlank, @Size(max=50))
- UUID membreId (@NotNull)
- String numeroMembre
- String nomMembre
- String emailMembre
- UUID organisationId (@NotNull)
- String nomOrganisation
- LocalDate dateDemande (@NotNull)
- BigDecimal fraisAdhesion (@NotNull, @DecimalMin(0, inclusive=false))
- BigDecimal montantPaye (@DecimalMin(0))
- String codeDevise (@NotBlank, @Pattern("^[A-Z]{3}$"))
- String statut (@NotBlank, @Pattern)
- LocalDate dateApprobation
- LocalDateTime datePaiement
- String methodePaiement (@Pattern)
- String referencePaiement (@Size(max=100))
- String motifRejet (@Size(max=1000))
- String observations (@Size(max=1000))
- String approuvePar (@Size(max=255))
- LocalDate dateValidation
+ isPayeeIntegralement(): boolean
+ isEnAttentePaiement(): boolean
+ getMontantRestant(): BigDecimal
+ getPourcentagePaiement(): int
+ getJoursDepuisDemande(): long
+ getStatutLibelle(): String
+ getStatutSeverity(): String
+ getStatutIcon(): String
+ getMethodePaiementLibelle(): String
+ getDateDemandeFormatee(): String
+ getDateApprobationFormatee(): String
+ getDatePaiementFormatee(): String
+ getFraisAdhesionFormatte(): String
+ getMontantPayeFormatte(): String
+ getMontantRestantFormatte(): String
}
```
---
### 3.7 EvenementDTO
```java
public class EvenementDTO extends BaseDTO {
- String titre (@NotBlank, @Size(3-200))
- String description (@Size(max=2000))
- TypeEvenementMetier typeEvenement (@NotNull)
- StatutEvenement statut (@NotNull)
- PrioriteEvenement priorite
- LocalDate dateDebut (@NotNull, @Future)
- LocalDate dateFin
- LocalTime heureDebut
- LocalTime heureFin
- String lieu (@NotBlank, @Size(max=100))
- String adresse (@Size(max=200))
- String ville (@Size(max=50))
- String region (@Size(max=50))
- BigDecimal latitude (@DecimalMin(-90), @DecimalMax(90))
- BigDecimal longitude (@DecimalMin(-180), @DecimalMax(180))
- UUID associationId (@NotNull)
- String nomAssociation
- String organisateur (@Size(max=100))
- String emailOrganisateur (@Email, @Size(max=100))
- String telephoneOrganisateur (@Pattern)
- Integer capaciteMax (@Min(1), @Max(10000))
- Integer participantsInscrits (@Min(0))
- Integer participantsPresents (@Min(0))
- BigDecimal budget (@DecimalMin(0), @Digits)
- BigDecimal coutReel (@DecimalMin(0), @Digits)
- String codeDevise (@Pattern)
- Boolean inscriptionObligatoire
- LocalDate dateLimiteInscription
- Boolean evenementPublic
- Boolean recurrent
- String frequenceRecurrence (@Pattern)
- String instructions (@Size(max=500))
- String materielNecessaire (@Size(max=500))
- String conditionsMeteo (@Size(max=100))
- String imageUrl (@Size(max=255))
- String couleurTheme (@Pattern)
- LocalDateTime dateAnnulation
- String raisonAnnulation (@Size(max=500))
- Long annulePar
- String nomAnnulateur
+ estEnCours(): boolean
+ estTermine(): boolean
+ estAnnule(): boolean
+ estComplet(): boolean
+ getPlacesDisponibles(): int
+ getTauxRemplissage(): int
+ getTauxPresence(): int
+ sontInscriptionsOuvertes(): boolean
+ getDureeEnHeures(): long
+ estEvenementMultiJours(): boolean
+ getTypeEvenementLibelle(): String
+ getStatutLibelle(): String
+ getPrioriteLibelle(): String
+ getAdresseComplete(): String
+ hasCoordonnees(): boolean
+ getEcartBudgetaire(): BigDecimal
+ estBudgetDepasse(): boolean
}
```
---
### 3.8 DemandeAideDTO
```java
public class DemandeAideDTO extends BaseDTO {
- String numeroReference (@Pattern)
- TypeAide typeAide (@NotNull)
- String titre (@NotBlank, @Size(3-200))
- String description (@NotBlank, @Size(3-2000))
- String justification (@Size(max=2000))
- BigDecimal montantDemande (@DecimalMin(0, inclusive=false), @Digits)
- BigDecimal montantApprouve (@DecimalMin(0, inclusive=false), @Digits)
- BigDecimal montantVerse (@DecimalMin(0, inclusive=false), @Digits)
- String devise (@Pattern, default="XOF")
- UUID membreDemandeurId (@NotNull)
- String nomDemandeur
- String numeroMembreDemandeur
- String evaluateurId
- String evaluateurNom
- String approvateurId
- String approvateurNom
- UUID associationId (@NotNull)
- String nomAssociation
- StatutAide statut (@NotNull, default=EN_ATTENTE)
- PrioriteAide priorite (@NotNull, default=NORMALE)
- String motifRejet (@Size(max=500))
- String commentairesEvaluateur (@Size(max=1000))
- LocalDateTime dateSoumission
- LocalDateTime dateLimiteTraitement
- LocalDateTime dateEvaluation
- LocalDateTime dateApprobation
- LocalDateTime dateVersement
- LocalDateTime dateCloture
- List<PieceJustificativeDTO> piecesJustificatives
- List<BeneficiaireAideDTO> beneficiaires
- List<HistoriqueStatutDTO> historiqueStatuts
- List<CommentaireAideDTO> commentaires
- Map<String, Object> donneesPersonnalisees
- List<String> tags
- Boolean estConfidentielle
- Boolean necessiteSuivi
- Double scorePriorite
- Integer nombreVues
- LocalisationDTO localisation
- ContactUrgenceDTO contactUrgence
- LocalDate dateLimite
- Boolean justificatifsFournis
- String documentsJoints (@Size(max=1000))
- LocalDate dateDebutAide
- LocalDate dateFinAide
- UUID membreAidantId
- String nomAidant
- String modeVersement (@Size(max=50))
- String numeroTransaction (@Size(max=100))
- UUID rejeteParId
- String rejetePar
- LocalDateTime dateRejet
- String raisonRejet (@Size(max=500))
+ estModifiable(): boolean
+ peutEtreAnnulee(): boolean
+ estUrgente(): boolean
+ estTerminee(): boolean
+ estEnSucces(): boolean
+ getPourcentageAvancement(): double
+ getDelaiRestantHeures(): long
+ estDelaiDepasse(): boolean
+ getDureeTraitementJours(): long
+ getStatutLibelle(): String
+ getPrioriteLibelle(): String
+ approuver(UUID evaluateurId, String nomEvaluateur, BigDecimal montantApprouve, String commentaires): void
+ rejeter(UUID evaluateurId, String nomEvaluateur, String raison): void
+ demarrerAide(UUID aidantId, String nomAidant): void
+ terminerAvecVersement(BigDecimal montantVerse, String modeVersement, String numeroTransaction): void
+ incrementerVues(): void
+ genererNumeroReference(): String (static)
}
```
---
### 3.9 AuditLogDTO
```java
public class AuditLogDTO extends BaseDTO {
- String typeAction
- String severite
- String utilisateur
- String role
- String module
- String description
- String details
- String ipAddress
- String userAgent
- String sessionId
- LocalDateTime dateHeure
- String donneesAvant
- String donneesApres
- String entiteId
- String entiteType
}
```
---
## 4. ENUMS (Server API)
### 4.1 StatutMembre
```java
public enum StatutMembre {
ACTIF("Actif"),
INACTIF("Inactif"),
SUSPENDU("Suspendu"),
DEMISSIONNAIRE("Démissionnaire"),
EXCLU("Exclu");
- String libelle
+ getLibelle(): String
}
```
---
### 4.2 StatutOrganisation
```java
public enum StatutOrganisation {
ACTIVE("Active"),
INACTIVE("Inactive"),
SUSPENDUE("Suspendue"),
EN_CREATION("En création"),
DISSOUTE("Dissoute");
- String libelle
+ getLibelle(): String
}
```
---
### 4.3 TypeOrganisation
```java
public enum TypeOrganisation {
LIONS_CLUB("Lions Club"),
ASSOCIATION("Association"),
FEDERATION("Fédération"),
COOPERATIVE("Coopérative"),
MUTUELLE("Mutuelle"),
SYNDICAT("Syndicat"),
FONDATION("Fondation"),
ONG("ONG");
- String libelle
+ getLibelle(): String
}
```
---
### 4.4 StatutCotisation
```java
public enum StatutCotisation {
EN_ATTENTE("En attente"),
PAYEE("Payée"),
PARTIELLEMENT_PAYEE("Partiellement payée"),
EN_RETARD("En retard"),
ANNULEE("Annulée"),
REMBOURSEE("Remboursée");
- String libelle
+ getLibelle(): String
}
```
---
### 4.5 StatutEvenement
```java
public enum StatutEvenement {
PLANIFIE("Planifié"),
CONFIRME("Confirmé"),
EN_COURS("En cours"),
TERMINE("Terminé"),
ANNULE("Annulé"),
REPORTE("Reporté");
- String libelle
+ getLibelle(): String
}
```
---
### 4.6 TypeEvenementMetier
```java
public enum TypeEvenementMetier {
ASSEMBLEE_GENERALE("Assemblée Générale"),
REUNION("Réunion"),
FORMATION("Formation"),
CONFERENCE("Conférence"),
ATELIER("Atelier"),
SEMINAIRE("Séminaire"),
EVENEMENT_SOCIAL("Événement Social"),
MANIFESTATION("Manifestation"),
CELEBRATION("Célébration"),
AUTRE("Autre");
- String libelle
+ getLibelle(): String
}
```
---
### 4.7 StatutAide
```java
public enum StatutAide {
BROUILLON("Brouillon"),
SOUMISE("Soumise"),
EN_ATTENTE("En attente"),
EN_COURS_EVALUATION("En cours d'évaluation"),
INFORMATIONS_REQUISES("Informations requises"),
APPROUVEE("Approuvée"),
APPROUVEE_PARTIELLEMENT("Approuvée partiellement"),
EN_COURS_TRAITEMENT("En cours de traitement"),
EN_COURS_VERSEMENT("En cours de versement"),
VERSEE("Versée"),
LIVREE("Livrée"),
TERMINEE("Terminée"),
REJETEE("Rejetée"),
ANNULEE("Annulée"),
EXPIREE("Expirée"),
SUSPENDUE("Suspendue"),
EN_SUIVI("En suivi"),
CLOTUREE("Clôturée");
- String libelle
+ permetModification(): boolean
+ permetAnnulation(): boolean
+ isEstFinal(): boolean
+ isSucces(): boolean
+ getLibelle(): String
}
```
---
### 4.8 TypeAide
```java
public enum TypeAide {
FINANCIERE("Aide financière"),
MATERIELLE("Aide matérielle"),
ALIMENTAIRE("Aide alimentaire"),
MEDICALE("Aide médicale"),
SCOLAIRE("Aide scolaire"),
LOGEMENT("Aide au logement"),
EMPLOI("Aide à l'emploi"),
FORMATION("Aide à la formation"),
AUTRE("Autre");
- String libelle
+ getLibelle(): String
}
```
---
### 4.9 PrioriteAide
```java
public enum PrioriteAide {
BASSE("Basse"),
NORMALE("Normale"),
HAUTE("Haute"),
URGENTE("Urgente"),
CRITIQUE("Critique");
- String libelle
+ isUrgente(): boolean
+ getLibelle(): String
}
```
---
## 5. SERVICES SERVEUR (Server Implementation)
### 5.1 MembreService
```java
@ApplicationScoped
public class MembreService {
@Inject MembreRepository membreRepository;
@PersistenceContext EntityManager entityManager;
+ creerMembre(Membre membre): Membre @Transactional
+ mettreAJourMembre(UUID id, Membre membreMiseAJour): Membre @Transactional
+ desactiverMembre(UUID id): void @Transactional
+ genererNumeroMembre(): String (private)
+ compterMembresActifs(): long
+ listerMembresActifs(Page page, Sort sort): List<Membre>
+ rechercherMembres(String recherche, Page page, Sort sort): List<Membre>
+ obtenirStatistiquesAvancees(): Map<String, Object>
+ convertToDTO(Membre membre): MembreDTO
+ convertFromDTO(MembreDTO dto): Membre
+ convertToDTOList(List<Membre> membres): List<MembreDTO>
+ updateFromDTO(Membre membre, MembreDTO dto): void
+ rechercheAvancee(MembreSearchCriteria criteria, Page page, Sort sort): MembreSearchResultDTO
}
```
**Dépendances :**
- `MembreRepository`
- `EntityManager`
---
### 5.2 OrganisationService
```java
@ApplicationScoped
public class OrganisationService {
@Inject OrganisationRepository organisationRepository;
+ creerOrganisation(Organisation organisation): Organisation @Transactional
+ mettreAJourOrganisation(UUID id, Organisation organisationMiseAJour, String utilisateur): Organisation @Transactional
+ supprimerOrganisation(UUID id, String utilisateur): void @Transactional
+ trouverParId(UUID id): Optional<Organisation>
+ trouverParEmail(String email): Optional<Organisation>
+ listerOrganisationsActives(): List<Organisation>
+ listerOrganisationsActives(int page, int size): List<Organisation>
+ rechercherOrganisations(String recherche, int page, int size): List<Organisation>
+ rechercheAvancee(...): List<Organisation>
+ activerOrganisation(UUID id, String utilisateur): Organisation @Transactional
+ suspendreOrganisation(UUID id, String utilisateur): Organisation @Transactional
+ obtenirStatistiques(): Map<String, Object>
+ convertToDTO(Organisation organisation): OrganisationDTO
+ convertFromDTO(OrganisationDTO dto): Organisation
}
```
**Dépendances :**
- `OrganisationRepository`
---
### 5.3 TypeOrganisationService
```java
@ApplicationScoped
public class TypeOrganisationService {
@Inject TypeOrganisationRepository repository;
@Inject KeycloakService keycloakService;
+ listTypes(Boolean onlyActifs): List<TypeOrganisationDTO>
+ getTypeById(UUID id): Optional<TypeOrganisationDTO>
+ create(TypeOrganisationDTO dto): TypeOrganisationDTO @Transactional
+ update(UUID id, TypeOrganisationDTO dto): TypeOrganisationDTO @Transactional
+ delete(UUID id): void @Transactional
+ convertToDTO(TypeOrganisationEntity entity): TypeOrganisationDTO
+ convertFromDTO(TypeOrganisationDTO dto): TypeOrganisationEntity
}
```
**Dépendances :**
- `TypeOrganisationRepository`
- `KeycloakService`
---
### 5.4 Autres Services
- `CotisationService`
- `AdhesionService`
- `EvenementService`
- `DemandeAideService`
- `AuditService`
- `KeycloakService`
- `NotificationService`
- `ExportService`
- `PaiementService`
- `WaveService`
---
## 6. RESOURCES REST (Server Implementation)
### 6.1 MembreResource
```java
@Path("/api/membres")
@ApplicationScoped
public class MembreResource {
@Inject MembreService membreService;
@GET
@PermitAll
+ listerMembres(@QueryParam("page") int page, @QueryParam("size") int size): List<MembreDTO>
@GET
@Path("/{id}")
@PermitAll
+ obtenirMembre(@PathParam("id") UUID id): MembreDTO
@POST
@PermitAll
+ creerMembre(MembreDTO dto): Response
@PUT
@Path("/{id}")
@PermitAll
+ mettreAJourMembre(@PathParam("id") UUID id, MembreDTO dto): Response
@DELETE
@Path("/{id}")
@PermitAll
+ supprimerMembre(@PathParam("id") UUID id): Response
@GET
@Path("/recherche")
@PermitAll
+ rechercherMembres(@QueryParam("q") String query, @QueryParam("page") int page, @QueryParam("size") int size): List<MembreDTO>
@GET
@Path("/statistiques")
@PermitAll
+ obtenirStatistiques(): Map<String, Object>
}
```
---
### 6.2 OrganisationResource
```java
@Path("/api/organisations")
@ApplicationScoped
public class OrganisationResource {
@Inject OrganisationService organisationService;
@GET
@PermitAll
+ listerToutes(@QueryParam("page") int page, @QueryParam("size") int size): List<OrganisationDTO>
@GET
@Path("/{id}")
@PermitAll
+ obtenirOrganisation(@PathParam("id") UUID id): OrganisationDTO
@POST
@PermitAll
+ creerOrganisation(OrganisationDTO dto): Response
@PUT
@Path("/{id}")
@PermitAll
+ mettreAJourOrganisation(@PathParam("id") UUID id, OrganisationDTO dto): Response
@DELETE
@Path("/{id}")
@PermitAll
+ supprimerOrganisation(@PathParam("id") UUID id): Response
@GET
@Path("/recherche")
@PermitAll
+ rechercheAvancee(...): List<OrganisationDTO>
@POST
@Path("/{id}/activer")
@PermitAll
+ activerOrganisation(@PathParam("id") UUID id): Response
@POST
@Path("/{id}/suspendre")
@PermitAll
+ suspendreOrganisation(@PathParam("id") UUID id): Response
@GET
@Path("/statistiques")
@PermitAll
+ obtenirStatistiques(): Map<String, Object>
}
```
---
### 6.3 TypeOrganisationResource
```java
@Path("/api/types-organisations")
@ApplicationScoped
public class TypeOrganisationResource {
@Inject TypeOrganisationService service;
@GET
@PermitAll
+ listTypes(@QueryParam("onlyActifs") String onlyActifs): List<TypeOrganisationDTO>
@GET
@Path("/{id}")
@PermitAll
+ getTypeById(@PathParam("id") UUID id): TypeOrganisationDTO
@POST
@PermitAll
+ create(TypeOrganisationDTO dto): Response
@PUT
@Path("/{id}")
@PermitAll
+ update(@PathParam("id") UUID id, TypeOrganisationDTO dto): Response
@DELETE
@Path("/{id}")
@PermitAll
+ delete(@PathParam("id") UUID id): Response
}
```
---
### 6.4 Autres Resources
- `CotisationResource`
- `AdhesionResource`
- `EvenementResource`
- `DemandeAideResource`
- `AuditResource`
- `NotificationResource`
- `ExportResource`
- `DashboardResource`
- `HealthResource`
- `WaveResource`
- `PreferencesResource`
---
## 7. DTOs CLIENT (Client)
### 7.1 MembreDTO (Client)
```java
public class MembreDTO implements Serializable {
- UUID id
- String numeroMembre (@Size(max=50))
- String nom (@NotBlank, @Size(2-50), @Pattern)
- String prenom (@NotBlank, @Size(2-50), @Pattern)
- String email (@NotBlank, @Email, @Size(max=100))
- String telephone (@Size(max=20))
- LocalDate dateNaissance (@Past)
- String adresse (@Size(max=200))
- String profession (@Size(max=100))
- String statutMatrimonial (@Size(max=20))
- String nationalite (@Size(max=50))
- String numeroIdentite (@Size(max=50))
- String typeIdentite (@Size(max=20))
- String photoUrl (@Size(max=255))
- String statut (@NotNull)
- UUID associationId (@NotNull)
- String associationNom
- LocalDateTime dateInscription
- LocalDateTime dateDerniereModification
- String creePar
- String modifiePar
- Boolean responsable
- LocalDate dateAdhesion
- String region (@Size(max=50))
- String ville (@Size(max=50))
- String quartier (@Size(max=50))
- String role (@Size(max=50))
// Propriétés dérivées (calculées)
+ getInitiales(): String
+ getTypeMembre(): String
+ getTypeSeverity(): String
+ getTypeIcon(): String
+ getStatutIcon(): String
+ getEntite(): String
+ getAnciennete(): String
+ getCotisationStatut(): String
+ getCotisationColor(): String
+ getDernierPaiement(): String
+ getTauxParticipation(): String
+ getEvenementsAnnee(): String
}
```
---
### 7.2 AssociationDTO (Client)
```java
@JsonIgnoreProperties(ignoreUnknown = true)
public class AssociationDTO implements Serializable {
- UUID id
- String nom (@NotBlank)
- String nomCourt
- String description
- String adresse
- String telephone
- String email
- String siteWeb
- String logo
- String typeAssociation (@NotNull, @JsonProperty("typeOrganisation"))
- LocalDate dateFondation (@JsonProperty("dateFondation"))
- String numeroRegistre (@JsonProperty("numeroEnregistrement"))
- String statut
- Integer nombreMembres
- Integer nombreAdministrateurs
- String responsablePrincipal
- String telephoneResponsable
- String emailResponsable
- LocalDateTime dateDerniereActivite
- LocalDateTime dateCreation
- LocalDateTime dateModification
- Long version
- Boolean actif
- String region
- String ville
- String quartier
- String pays
- String codePostal
- String activitesPrincipales
- String objectifs
- String partenaires
- String certifications
- String reseauxSociaux
- String notes
- Boolean organisationPublique
- Boolean accepteNouveauxMembres
- Boolean cotisationObligatoire
- BigDecimal budgetAnnuel
- String devise
- BigDecimal montantCotisationAnnuelle
- String telephoneSecondaire
- String emailSecondaire
- UUID organisationParenteId
- String nomOrganisationParente
- Integer niveauHierarchique
- BigDecimal latitude
- BigDecimal longitude
+ getTypeLibelle(): String
+ getStatutLibelle(): String
+ getStatutSeverity(): String
+ getAdresseComplete(): String
}
```
---
### 7.3 Autres DTOs Client
- `TypeOrganisationClientDTO`
- `CotisationDTO`
- `AdhesionDTO`
- `EvenementDTO`
- `DemandeAideDTO`
- `AuditLogDTO`
- `AnalyticsDataDTO`
- `WaveBalanceDTO`
- `WaveCheckoutSessionDTO`
---
## 8. SERVICES CLIENT (Client)
### 8.1 MembreService (REST Client)
```java
@RestClient
@RegisterRestClient(configKey = "unionflow-api")
public interface MembreService {
@GET
@Path("/api/membres")
+ listerToutes(@QueryParam("page") int page, @QueryParam("size") int size): List<MembreDTO>
@GET
@Path("/api/membres/{id}")
+ obtenirMembre(@PathParam("id") UUID id): MembreDTO
@POST
@Path("/api/membres")
+ creer(MembreDTO dto): MembreDTO
@PUT
@Path("/api/membres/{id}")
+ modifier(@PathParam("id") UUID id, MembreDTO dto): MembreDTO
@DELETE
@Path("/api/membres/{id}")
+ supprimer(@PathParam("id") UUID id): void
@GET
@Path("/api/membres/recherche")
+ rechercher(@QueryParam("q") String query, @QueryParam("page") int page, @QueryParam("size") int size): List<MembreDTO>
}
```
---
### 8.2 AssociationService (REST Client)
```java
@RestClient
@RegisterRestClient(configKey = "unionflow-api")
public interface AssociationService {
@GET
@Path("/api/organisations")
+ listerToutes(@QueryParam("page") int page, @QueryParam("size") int size): List<AssociationDTO>
@GET
@Path("/api/organisations/{id}")
+ obtenirOrganisation(@PathParam("id") UUID id): AssociationDTO
@POST
@Path("/api/organisations")
+ creerOrganisation(AssociationDTO dto): AssociationDTO
@PUT
@Path("/api/organisations/{id}")
+ mettreAJourOrganisation(@PathParam("id") UUID id, AssociationDTO dto): AssociationDTO
@DELETE
@Path("/api/organisations/{id}")
+ supprimerOrganisation(@PathParam("id") UUID id): void
@GET
@Path("/api/organisations/recherche")
+ rechercheAvancee(...): List<AssociationDTO>
@POST
@Path("/api/organisations/{id}/activer")
+ activerOrganisation(@PathParam("id") UUID id): void
@POST
@Path("/api/organisations/{id}/suspendre")
+ suspendreOrganisation(@PathParam("id") UUID id): void
@GET
@Path("/api/organisations/statistiques")
+ obtenirStatistiques(): Map<String, Object>
}
```
---
### 8.3 Autres Services Client
- `TypeOrganisationClientService`
- `CotisationService`
- `AdhesionService`
- `EvenementService`
- `DemandeAideService`
- `AuditService`
- `NotificationClientService`
- `ExportClientService`
- `PreferencesService`
- `WaveService`
- `ValidationService`
---
## 9. BEANS JSF (Client - View)
### 9.1 MembreInscriptionBean
```java
@Named("membreInscriptionBean")
@ViewScoped
public class MembreInscriptionBean implements Serializable {
@Inject @RestClient MembreService membreService;
@Inject @RestClient AssociationService associationService;
@Inject ValidationService validationService;
// Champs du formulaire
- String prenom
- String nom
- LocalDate dateNaissance
- String sexe
- String email
- String telephoneMobile
- String adresse
- String ville
- String codePostal
- String region
- String pays
- String profession
- String situationMatrimoniale
- String nationalite
- String contactUrgenceNom
- String contactUrgenceTelephone
- String contactUrgenceLien
- String organisationId
- String typeAdhesion
- String numeroGenere
- List<AssociationDTO> organisations
- int etapeCourante
- String membreIdString
- boolean modeModification
- MembreDTO membreSelectionne
+ init(): void @PostConstruct
+ chargerMembreSiModification(): void
+ inscrire(): String
+ enregistrerBrouillon(): String
+ preparerNouveauMembre(): void
+ peutAccepterNouveauMembre(): boolean
+ isEtapePersonnelleComplete(): boolean
+ isEtapeCoordonneeComplete(): boolean
+ isEtapeAdhesionComplete(): boolean
+ isEtapeDocumentsComplete(): boolean
+ getProgressionPourcentage(): int
}
```
**Dépendances :**
- `MembreService` (REST Client)
- `AssociationService` (REST Client)
- `ValidationService`
---
### 9.2 MembreListeBean
```java
@Named("membreListeBean")
@ViewScoped
public class MembreListeBean implements Serializable {
@Inject @RestClient MembreService membreService;
@Inject @RestClient AssociationService associationService;
- List<MembreDTO> membres
- MembreDTO membreSelectionne
- String recherche
- String membreSelectionneIdString
- int page = 0
- int size = 20
+ init(): void @PostConstruct
+ chargerMembres(): void
+ rechercherMembres(): void
+ modifierMembre(MembreDTO membre): String
+ supprimerMembre(MembreDTO membre): void
+ basculerStatutMembre(MembreDTO membre): void
+ voirProfil(MembreDTO membre): String
+ chargerMembreSelectionne(): void
}
```
**Dépendances :**
- `MembreService` (REST Client)
- `AssociationService` (REST Client)
---
### 9.3 OrganisationsBean
```java
@Named("organisationsBean")
@ViewScoped
public class OrganisationsBean implements Serializable {
@Inject @RestClient AssociationService associationService;
@Inject @RestClient TypeOrganisationClientService typeOrganisationService;
- List<AssociationDTO> organisations
- AssociationDTO nouvelleOrganisation
- AssociationDTO organisationSelectionnee
- List<TypeOrganisationClientDTO> typesOrganisation
- Map<String, Object> statistiques
- String recherche
- String statutFiltre
- String typeFiltre
- int page = 0
- int size = 20
- String statutActive = "ACTIVE"
+ init(): void @PostConstruct
+ chargerOrganisations(): void
+ chargerStatistiques(): void
+ chargerTypesOrganisation(): void
+ preparerNouvelleOrganisation(): void
+ creerOrganisation(): void
+ modifierOrganisation(): void
+ supprimerOrganisation(AssociationDTO org): void
+ basculerStatutOrganisation(AssociationDTO org): void
+ rechercherOrganisations(String query): void
+ recharger(): void
+ setOrganisationSelectionnee(AssociationDTO org): void
}
```
**Dépendances :**
- `AssociationService` (REST Client)
- `TypeOrganisationClientService` (REST Client)
---
### 9.4 Autres Beans
- `OrganisationDetailBean`
- `TypeOrganisationsAdminBean`
- `CotisationsBean`
- `CotisationsGestionBean`
- `AdhesionsBean`
- `EvenementsBean`
- `DemandesAideBean`
- `DashboardBean`
- `AuditBean`
- `UserSession`
- `LoginBean`
- `PreferencesBean`
- `ParametresBean`
- `SuperAdminBean`
- `UtilisateursBean`
- `EntitesGestionBean`
- `MembreRechercheBean`
- `MembreProfilBean`
- `MembreDashboardBean`
- `MembreCotisationBean`
- `PersonnelBean`
- `FavorisBean`
- `RapportsBean`
- `RolesBean`
- `SecurityStatusBean`
- `SouscriptionBean`
- `WaveBean`
- `FormulaireBean`
- `AdminFormulaireBean`
- `DocumentsBean`
- `DemandesBean`
- `ConfigurationBean`
- `GuideBean`
- `GuestPreferences`
- `NavigationBean`
- `HelloView`
---
## 10. SÉCURITÉ (Client)
### 10.1 AuthenticationFilter
```java
@WebFilter(urlPatterns = "/pages/*")
public class AuthenticationFilter implements Filter {
@Inject JwtTokenManager tokenManager;
@Inject UserSession userSession;
+ doFilter(ServletRequest request, ServletResponse response, FilterChain chain): void
+ init(FilterConfig filterConfig): void
+ destroy(): void
}
```
---
### 10.2 JwtClientRequestFilter
```java
@Provider
public class JwtClientRequestFilter implements ClientRequestFilter {
@Inject JwtTokenManager tokenManager;
+ filter(ClientRequestContext requestContext): void
}
```
---
### 10.3 JwtTokenManager
```java
@ApplicationScoped
public class JwtTokenManager {
- String accessToken
- String refreshToken
- LocalDateTime tokenExpiry
+ getAccessToken(): String
+ setAccessToken(String token): void
+ getRefreshToken(): String
+ setRefreshToken(String token): void
+ isTokenValid(): boolean
+ clearTokens(): void
}
```
---
### 10.4 UserSession
```java
@Named("userSession")
@SessionScoped
public class UserSession implements Serializable {
- String username
- String email
- String nomComplet
- String typeCompte
- List<String> roles
- String accessToken
- String refreshToken
+ init(): void @PostConstruct
+ logout(): String
+ isAuthenticated(): boolean
+ hasRole(String role): boolean
+ isSuperAdmin(): boolean
+ isAdmin(): boolean
+ isMembre(): boolean
}
```
---
## 11. DIAGRAMME DE RELATIONS
### 11.1 Relations Entités
```
BaseEntity (abstract)
├── Membre
│ └── @ManyToOne → Organisation
├── Organisation
│ ├── @OneToMany → Membre
│ └── Auto-référence (organisationParenteId)
├── TypeOrganisationEntity
├── Cotisation
│ └── @ManyToOne → Membre
├── Adhesion
│ ├── @ManyToOne → Membre
│ └── @ManyToOne → Organisation
├── Evenement
│ ├── @ManyToOne → Organisation
│ ├── @ManyToOne → Membre (organisateur)
│ └── @OneToMany → InscriptionEvenement
├── InscriptionEvenement
│ ├── @ManyToOne → Membre
│ └── @ManyToOne → Evenement
├── DemandeAide
│ ├── @ManyToOne → Membre (demandeur)
│ ├── @ManyToOne → Membre (evaluateur)
│ └── @ManyToOne → Organisation
└── AuditLog
```
### 11.2 Relations Services
```
MembreService
└── @Inject → MembreRepository
└── extends → BaseRepository<Membre>
OrganisationService
└── @Inject → OrganisationRepository
└── extends → BaseRepository<Organisation>
TypeOrganisationService
├── @Inject → TypeOrganisationRepository
│ └── extends → BaseRepository<TypeOrganisationEntity>
└── @Inject → KeycloakService
```
### 11.3 Relations REST
```
MembreResource
└── @Inject → MembreService
OrganisationResource
└── @Inject → OrganisationService
TypeOrganisationResource
└── @Inject → TypeOrganisationService
```
### 11.4 Relations Client
```
MembreInscriptionBean
├── @Inject @RestClient → MembreService (interface)
├── @Inject @RestClient → AssociationService (interface)
└── @Inject → ValidationService
MembreListeBean
├── @Inject @RestClient → MembreService (interface)
└── @Inject @RestClient → AssociationService (interface)
OrganisationsBean
├── @Inject @RestClient → AssociationService (interface)
└── @Inject @RestClient → TypeOrganisationClientService (interface)
```
---
## 12. PATTERNS ET ARCHITECTURE
### 12.1 Patterns Utilisés
1. **Repository Pattern** : `BaseRepository<T>` avec implémentations spécialisées
2. **DTO Pattern** : Séparation entités JPA / DTOs API
3. **Service Layer** : Logique métier dans les services
4. **REST Client Pattern** : Interfaces MicroProfile Rest Client côté client
5. **Bean Pattern** : Beans JSF pour la présentation
6. **Filter Pattern** : Filtres pour authentification et JWT
7. **Base Entity Pattern** : `BaseEntity` pour audit et soft delete
### 12.2 Architecture en Couches
```
┌─────────────────────────────────────┐
│ CLIENT (JSF/PrimeFaces) │
│ - Beans (View) │
│ - DTOs Client │
│ - Services REST Client │
└─────────────────────────────────────┘
↕ HTTP/REST
┌─────────────────────────────────────┐
│ SERVER API │
│ - Resources REST (JAX-RS) │
│ - Services │
│ - Repositories │
└─────────────────────────────────────┘
↕ JPA
┌─────────────────────────────────────┐
│ DATABASE │
│ - Entités JPA │
│ - Relations │
└─────────────────────────────────────┘
```
---
## 13. POINTS D'AMÉLIORATION IDENTIFIÉS
### 13.1 Modélisation
1. **Relations manquantes** :
- Pas de relation explicite `Membre``Cotisation` (actuellement via `@ManyToOne` dans `Cotisation`)
- Pas de relation `Organisation``Evenement` (actuellement via `@ManyToOne` dans `Evenement`)
2. **Redondance** :
- `MembreDTO` existe côté serveur ET client avec des différences
- `AssociationDTO` (client) vs `OrganisationDTO` (serveur) - alignement partiel
3. **Champs optionnels non persistés** :
- Dans `MembreInscriptionBean`, plusieurs champs (sexe, contactUrgence, etc.) ne sont pas dans `MembreDTO` serveur
4. **Enums vs Entités** :
- `TypeOrganisation` existe en Enum ET en Entité (`TypeOrganisationEntity`) - risque de désynchronisation
### 13.2 Suggestions d'amélioration
1. **Unifier les DTOs** : Créer un seul DTO partagé ou mapper automatiquement
2. **Compléter les relations JPA** : Ajouter les relations bidirectionnelles manquantes
3. **Persister tous les champs** : Ajouter les champs manquants dans `Membre` ou créer une entité `ContactUrgence`
4. **Synchroniser Enum/Entité** : Utiliser uniquement l'entité `TypeOrganisationEntity` ou synchroniser automatiquement
5. **Audit complet** : S'assurer que tous les champs d'audit sont remplis automatiquement
6. **Validation cohérente** : Aligner les validations entre client et serveur
---
## 14. CONCLUSION
Ce diagramme de classes représente l'architecture complète d'UnionFlow avec :
- **9 entités JPA** principales
- **10+ repositories** spécialisés
- **15+ DTOs** serveur et client
- **10+ services** métier
- **15+ resources REST**
- **30+ beans JSF**
- **10+ enums** de statuts et types
L'architecture suit les principes DRY et WOU avec des composants réutilisables et une séparation claire des responsabilités.
---
**Date de génération** : 2025-01-29
**Version** : 1.0