Files
unionflow-server-api/MCD_UNIONFLOW.puml
dahoud a8bfbfcc1b docs: Ajout MCD UnionFlow en format PlantUML
Modèle Conceptuel de Données complet avec:
- 9 entités JPA (BaseEntity + 8 entités métier)
- Tous les attributs avec contraintes (PK, FK, unique, not null, etc.)
- Relations JPA (@ManyToOne, @OneToMany)
- Enums (TypeEvenement, StatutEvenement, StatutInscription, TypeAide, StatutAide)
- Notes explicatives sur les règles métier
- Hiérarchie Organisation (auto-référence)
- Génération automatique de champs

Format PlantUML pour visualisation avec outils UML.
2025-11-29 23:56:07 +00:00

481 lines
14 KiB
Plaintext

@startuml MCD_UnionFlow
!theme plain
skinparam linetype ortho
skinparam packageStyle rectangle
skinparam classAttributeIconSize 0
title Modèle Conceptuel de Données - UnionFlow
' ============================================
' ENTITÉS DE BASE
' ============================================
abstract class BaseEntity {
{abstract} --
+ {PK} id : UUID <<generated>>
+ dateCreation : LocalDateTime <<not null>>
+ dateModification : LocalDateTime
+ creePar : String
+ modifiePar : String
+ version : Long <<version>>
+ actif : Boolean <<not null, default=true>>
--
+ onCreate() : void <<@PrePersist>>
+ onUpdate() : void <<@PreUpdate>>
}
' ============================================
' ENTITÉS MÉTIER
' ============================================
class Organisation {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ nom : String <<not null, length=200>>
+ nomCourt : String <<length=50>>
+ typeOrganisation : String <<not null, length=50>>
+ statut : String <<not null, length=50>>
+ description : String <<length=2000>>
+ dateFondation : LocalDate
+ numeroEnregistrement : String <<unique, length=100>>
--
' Contact
+ email : String <<unique, not null, length=255>>
+ telephone : String <<length=20>>
+ telephoneSecondaire : String <<length=20>>
+ emailSecondaire : String <<length=255>>
--
' Adresse
+ adresse : String <<length=500>>
+ ville : String <<length=100>>
+ codePostal : String <<length=20>>
+ region : String <<length=100>>
+ pays : String <<length=100>>
+ latitude : BigDecimal <<precision=9,scale=6>>
+ longitude : BigDecimal <<precision=9,scale=6>>
--
' Web
+ siteWeb : String <<length=500>>
+ logo : String <<length=500>>
+ reseauxSociaux : String <<length=1000>>
--
' Hiérarchie
+ organisationParenteId : UUID
+ niveauHierarchique : Integer <<not null, default=0>>
--
' Statistiques
+ nombreMembres : Integer <<not null, default=0>>
+ nombreAdministrateurs : Integer <<not null, default=0>>
--
' Finances
+ budgetAnnuel : BigDecimal <<precision=14,scale=2>>
+ devise : String <<length=3, default=XOF>>
+ cotisationObligatoire : Boolean <<not null, default=false>>
+ montantCotisationAnnuelle : BigDecimal <<precision=12,scale=2>>
--
' Compléments
+ objectifs : String <<length=2000>>
+ activitesPrincipales : String <<length=2000>>
+ certifications : String <<length=500>>
+ partenaires : String <<length=1000>>
+ notes : String <<length=1000>>
+ organisationPublique : Boolean <<not null, default=true>>
+ accepteNouveauxMembres : Boolean <<not null, default=true>>
--
+ getNomComplet() : String
+ getAncienneteAnnees() : int
+ isRecente() : boolean
+ isActive() : boolean
+ ajouterMembre() : void
+ retirerMembre() : void
+ activer(String utilisateur) : void
+ suspendre(String utilisateur) : void
+ dissoudre(String utilisateur) : void
}
class Membre {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ numeroMembre : String <<unique, not null, length=20>>
+ prenom : String <<not null, length=100>>
+ nom : String <<not null, length=100>>
+ email : String <<unique, not null, length=255>>
+ motDePasse : String <<length=255>>
+ telephone : String <<length=20>>
+ dateNaissance : LocalDate <<not null>>
+ dateAdhesion : LocalDate <<not null>>
+ roles : String <<length=500>>
--
+ getNomComplet() : String
+ isMajeur() : boolean
+ getAge() : int
}
class TypeOrganisationEntity {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ code : String <<unique, not null, length=50>>
+ libelle : String <<not null, length=150>>
+ description : String <<length=500>>
+ ordreAffichage : Integer
}
class Cotisation {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ numeroReference : String <<unique, not null, length=50>>
+ typeCotisation : String <<not null, length=50>>
+ montantDu : BigDecimal <<not null, precision=12,scale=2>>
+ montantPaye : BigDecimal <<not null, default=0, precision=12,scale=2>>
+ codeDevise : String <<not null, length=3, pattern=^[A-Z]{3}$>>
+ statut : String <<not null, length=30>>
+ dateEcheance : LocalDate <<not null>>
+ datePaiement : LocalDateTime
+ description : String <<length=500>>
+ periode : String <<length=20>>
+ annee : Integer <<not null, min=2020, max=2100>>
+ mois : Integer <<min=1, max=12>>
+ observations : String <<length=1000>>
+ recurrente : Boolean <<not null, default=false>>
+ nombreRappels : Integer <<not null, default=0>>
+ dateDernierRappel : LocalDateTime
+ valideParId : UUID
+ nomValidateur : String <<length=100>>
+ dateValidation : LocalDateTime
+ methodePaiement : String <<length=50>>
+ referencePaiement : String <<length=100>>
--
+ getMontantRestant() : BigDecimal
+ isEntierementPayee() : boolean
+ isEnRetard() : boolean
+ genererNumeroReference() : String <<static>>
}
class Adhesion {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ numeroReference : String <<unique, not null, length=50>>
+ dateDemande : LocalDate <<not null>>
+ fraisAdhesion : BigDecimal <<not null, precision=12,scale=2>>
+ montantPaye : BigDecimal <<not null, default=0, precision=12,scale=2>>
+ codeDevise : String <<not null, length=3, pattern=^[A-Z]{3}$>>
+ statut : String <<not null, length=30>>
+ dateApprobation : LocalDate
+ datePaiement : LocalDateTime
+ methodePaiement : String <<length=20>>
+ referencePaiement : String <<length=100>>
+ motifRejet : String <<length=1000>>
+ observations : String <<length=1000>>
+ approuvePar : String <<length=255>>
+ dateValidation : LocalDate
--
+ isPayeeIntegralement() : boolean
+ isEnAttentePaiement() : boolean
+ getMontantRestant() : BigDecimal
}
class Evenement {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ titre : String <<not null, length=200>>
+ description : String <<length=2000>>
+ dateDebut : LocalDateTime <<not null>>
+ dateFin : LocalDateTime
+ lieu : String <<length=500>>
+ adresse : String <<length=1000>>
+ typeEvenement : TypeEvenement <<enum>>
+ statut : StatutEvenement <<enum, not null, default=PLANIFIE>>
+ capaciteMax : Integer <<min=0>>
+ prix : BigDecimal <<precision=10,scale=2>>
+ inscriptionRequise : Boolean <<not null, default=false>>
+ dateLimiteInscription : LocalDateTime
+ instructionsParticulieres : String <<length=1000>>
+ contactOrganisateur : String <<length=500>>
+ materielRequis : String <<length=2000>>
+ visiblePublic : Boolean <<not null, default=true>>
--
+ isOuvertAuxInscriptions() : boolean
+ getNombreInscrits() : int
+ isComplet() : boolean
+ isEnCours() : boolean
+ isTermine() : boolean
+ getDureeEnHeures() : Long
+ getPlacesRestantes() : Integer
+ isMemberInscrit(UUID membreId) : boolean
+ getTauxRemplissage() : Double
}
class InscriptionEvenement {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ dateInscription : LocalDateTime <<not null, default=now()>>
+ statut : StatutInscription <<enum, default=CONFIRMEE>>
+ commentaire : String <<length=500>>
--
+ isConfirmee() : boolean
+ isEnAttente() : boolean
+ isAnnulee() : boolean
+ confirmer() : void
+ annuler(String commentaire) : void
+ mettreEnAttente(String commentaire) : void
+ refuser(String commentaire) : void
}
class DemandeAide {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ titre : String <<not null, length=200>>
+ description : String <<not null, TEXT>>
+ typeAide : TypeAide <<enum, not null>>
+ statut : StatutAide <<enum, not null>>
+ montantDemande : BigDecimal <<precision=10,scale=2>>
+ montantApprouve : BigDecimal <<precision=10,scale=2>>
+ dateDemande : LocalDateTime <<not null>>
+ dateEvaluation : LocalDateTime
+ dateVersement : LocalDateTime
+ justification : String <<TEXT>>
+ commentaireEvaluation : String <<TEXT>>
+ urgence : Boolean <<not null, default=false>>
+ documentsFournis : String
--
+ isEnAttente() : boolean
+ isApprouvee() : boolean
+ isRejetee() : boolean
+ isUrgente() : boolean
+ getPourcentageApprobation() : BigDecimal
}
class AuditLog {
+ {PK} id : UUID <<inherited>>
+ dateCreation : LocalDateTime <<inherited>>
+ dateModification : LocalDateTime <<inherited>>
+ creePar : String <<inherited>>
+ modifiePar : String <<inherited>>
+ version : Long <<inherited>>
+ actif : Boolean <<inherited>>
--
+ typeAction : String <<not null, length=50>>
+ severite : String <<not null, length=20>>
+ utilisateur : String <<length=255>>
+ role : String <<length=50>>
+ module : String <<length=50>>
+ description : String <<length=500>>
+ details : String <<TEXT>>
+ ipAddress : String <<length=45>>
+ userAgent : String <<length=500>>
+ sessionId : String <<length=255>>
+ dateHeure : LocalDateTime <<not null>>
+ donneesAvant : String <<TEXT>>
+ donneesApres : String <<TEXT>>
+ entiteId : String <<length=255>>
+ entiteType : String <<length=100>>
}
' ============================================
' ENUMS
' ============================================
enum TypeEvenement {
ASSEMBLEE_GENERALE
REUNION
FORMATION
CONFERENCE
ATELIER
SEMINAIRE
EVENEMENT_SOCIAL
MANIFESTATION
CELEBRATION
AUTRE
}
enum StatutEvenement {
PLANIFIE
CONFIRME
EN_COURS
TERMINE
ANNULE
REPORTE
}
enum StatutInscription {
CONFIRMEE
EN_ATTENTE
ANNULEE
REFUSEE
}
enum TypeAide {
FINANCIERE
MATERIELLE
ALIMENTAIRE
MEDICALE
SCOLAIRE
LOGEMENT
EMPLOI
FORMATION
AUTRE
}
enum StatutAide {
BROUILLON
SOUMISE
EN_ATTENTE
EN_COURS_EVALUATION
INFORMATIONS_REQUISES
APPROUVEE
APPROUVEE_PARTIELLEMENT
EN_COURS_TRAITEMENT
EN_COURS_VERSEMENT
VERSEE
LIVREE
TERMINEE
REJETEE
ANNULEE
EXPIREE
SUSPENDUE
EN_SUIVI
CLOTUREE
}
' ============================================
' RELATIONS
' ============================================
BaseEntity <|-- Organisation
BaseEntity <|-- Membre
BaseEntity <|-- TypeOrganisationEntity
BaseEntity <|-- Cotisation
BaseEntity <|-- Adhesion
BaseEntity <|-- Evenement
BaseEntity <|-- InscriptionEvenement
BaseEntity <|-- DemandeAide
BaseEntity <|-- AuditLog
' Relations Organisation
Organisation "1" *-- "0..*" Membre : "appartient à"
Organisation "0..1" --o "0..*" Organisation : "parente >\n(organisationParenteId)"
' Relations Membre
Membre "1" *-- "0..*" Cotisation : "a des"
Membre "1" *-- "0..*" Adhesion : "demande"
Membre "1" *-- "0..*" Evenement : "organise"
Membre "1" *-- "0..*" InscriptionEvenement : "s'inscrit"
Membre "1" *-- "0..*" DemandeAide : "demande (demandeur)"
Membre "0..1" *-- "0..*" DemandeAide : "évalue (evaluateur)"
' Relations Organisation (suite)
Organisation "1" *-- "0..*" Adhesion : "reçoit"
Organisation "1" *-- "0..*" Evenement : "organise"
Organisation "1" *-- "0..*" DemandeAide : "traite"
' Relations Evenement
Evenement "1" *-- "0..*" InscriptionEvenement : "a des inscriptions"
' Relations Enums
Evenement ..> TypeEvenement : "utilise"
Evenement ..> StatutEvenement : "utilise"
InscriptionEvenement ..> StatutInscription : "utilise"
DemandeAide ..> TypeAide : "utilise"
DemandeAide ..> StatutAide : "utilise"
note right of Organisation
**Hiérarchie** :
- organisationParenteId : UUID (référence)
- niveauHierarchique : 0 = racine
- Auto-référence pour structure hiérarchique
end note
note right of Membre
**Génération automatique** :
- numeroMembre : auto-généré si non fourni
- dateAdhesion : auto-générée à LocalDate.now() si null
- dateNaissance : auto-générée à il y a 18 ans si null
end note
note right of Cotisation
**Statuts possibles** :
- EN_ATTENTE
- PAYEE
- EN_RETARD
- PARTIELLEMENT_PAYEE
- ANNULEE
end note
note right of Adhesion
**Statuts possibles** :
- EN_ATTENTE
- APPROUVEE
- REJETEE
- ANNULEE
- EN_PAIEMENT
- PAYEE
end note
note right of Evenement
**Gestion des inscriptions** :
- inscriptionRequise : Boolean
- capaciteMax : Integer
- dateLimiteInscription : LocalDateTime
- Méthodes : isOuvertAuxInscriptions(),
getNombreInscrits(), isComplet()
end note
note right of DemandeAide
**Workflow d'aide** :
- demandeur : Membre (obligatoire)
- evaluateur : Membre (optionnel)
- organisation : Organisation (obligatoire)
- Statuts multiples avec workflow
end note
@enduml