# UnionFlow Server API - DTOs et Contrats ![Java](https://img.shields.io/badge/Java-17-blue) ![Maven](https://img.shields.io/badge/Maven-Central-green) ![License](https://img.shields.io/badge/License-Proprietary-red) Module API partagé UnionFlow - DTOs, Request/Response, Validation, Enums. --- ## 📋 Vue d'ensemble Ce module contient les **contrats d'API** partagés entre : - **Backend Quarkus** (unionflow-server-impl-quarkus) - **Frontend Web** (unionflow-client-quarkus-primefaces-freya) - **Mobile Flutter** (unionflow-mobile-apps) - via génération TypeScript/JSON ### Avantages ✅ **Type-safety** : Contrats Java typés ✅ **Validation centralisée** : Contraintes Jakarta Bean Validation ✅ **DRY** : Zéro duplication entre projets ✅ **Versioning** : Maven semantic versioning ✅ **Documentation** : Javadoc complète --- ## 🏗️ Structure ``` src/main/java/dev/lions/unionflow/server/api/ ├── dto/ # Data Transfer Objects │ ├── base/ # DTOs de base │ │ ├── BaseRequest.java │ │ └── BaseResponse.java │ ├── dashboard/ # Dashboard │ │ ├── DashboardStatsResponse.java │ │ ├── MembreDashboardSyntheseResponse.java │ │ └── UpcomingEventResponse.java │ ├── membre/ # Membres │ │ ├── request/ │ │ │ └── CreateMembreRequest.java │ │ └── response/ │ │ ├── MembreResponse.java │ └── MembreSummaryResponse.java │ ├── finance/ # Finance Workflow │ │ ├── request/ │ │ │ ├── ApproveTransactionRequest.java │ │ │ └── RejectTransactionRequest.java │ │ └── response/ │ │ ├── AdhesionResponse.java │ │ ├── TransactionApprovalResponse.java │ │ └── BudgetResponse.java │ ├── cotisation/ # Cotisations │ ├── evenement/ # Événements │ ├── solidarite/ # Demandes d'aide │ └── notification/ # Notifications ├── enums/ # Énumérations │ ├── membre/ │ │ ├── StatutMembre.java │ │ └── TypeMembre.java │ ├── finance/ │ │ ├── StatutApprobation.java │ │ ├── TypeTransaction.java │ │ └── BudgetPeriod.java │ ├── paiement/ │ │ ├── StatutPaiement.java │ │ └── ModePaiement.java │ └── notification/ │ └── TypeNotification.java ├── validation/ # Validateurs custom │ ├── annotations/ # Annotations validation │ │ ├── @ValidEmail │ │ ├── @ValidPhoneNumber │ │ └── @ValidAmount │ ├── validators/ # Implémentations │ │ ├── EmailValidator.java │ │ └── AmountValidator.java │ └── ValidationConstants.java # Constantes (regex, limites) └── exception/ # Exceptions API ├── ApiException.java ├── ValidationException.java └── ErrorResponse.java ``` --- ## 📦 Installation ### Maven Dependency Ajouter à votre `pom.xml` : ```xml dev.lions.unionflow unionflow-server-api 2.0.0 ``` ### Repository Gitea (Maven Registry) Configurer `~/.m2/settings.xml` : ```xml gitea-lionsdev ${env.GITEA_USERNAME} ${env.GITEA_TOKEN} gitea-lionsdev https://git.lions.dev/api/packages/lionsdev/maven ``` ### Variables d'environnement ```bash export GITEA_USERNAME=lionsdev export GITEA_TOKEN=your-gitea-token ``` --- ## 🎯 Utilisation ### 1. DTOs Request/Response #### Exemple : Créer un membre **Request DTO** : ```java @Data @NoArgsConstructor @AllArgsConstructor public class CreateMembreRequest { @NotBlank(message = "Le nom est requis") @Size(min = 2, max = 100) private String nom; @NotBlank(message = "Le prénom est requis") @Size(min = 2, max = 100) private String prenom; @ValidEmail private String email; @ValidPhoneNumber private String telephone; @NotNull private UUID organisationId; private TypeMembre typeMembre = TypeMembre.MEMBRE; } ``` **Response DTO** : ```java @Data @NoArgsConstructor @AllArgsConstructor public class MembreResponse extends BaseResponse { private UUID id; private String nom; private String prenom; private String email; private String telephone; private StatutMembre statut; private TypeMembre type; private String numeroMembre; private LocalDate dateAdhesion; private UUID organisationId; private String organisationNom; } ``` **Usage Backend** : ```java @POST @Path("/membres") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response createMembre(@Valid CreateMembreRequest request) { MembreResponse response = membreService.create(request); return Response.status(201).entity(response).build(); } ``` **Usage Frontend (REST Client)** : ```java @Path("/api/v1/membres") @RegisterRestClient(configKey = "unionflow-backend") public interface MembreRestClient { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) MembreResponse createMembre(@Valid CreateMembreRequest request); } ``` ### 2. Validation #### Annotations standard (Jakarta Bean Validation) ```java @NotNull // Non null @NotBlank // Non vide (String) @Size(min, max) // Taille min/max @Min(value) // Valeur minimale (nombres) @Max(value) // Valeur maximale (nombres) @Email // Format email @Pattern(regex) // Regex custom @Positive // > 0 @PositiveOrZero // >= 0 ``` #### Annotations custom UnionFlow ```java @ValidEmail // Email avec domaines autorisés @ValidPhoneNumber // Téléphone international (+225, +33, etc.) @ValidAmount // Montant positif, max 2 décimales @ValidNumeroMembre // Format: ORG-YYYY-NNNN @ValidPeriodeCotisation // Format: YYYY-MM ``` **Exemple d'utilisation** : ```java public class PaiementRequest { @ValidAmount(min = 100.0, max = 10_000_000.0) private BigDecimal montant; @ValidPhoneNumber private String telephonePaiement; @NotNull @Pattern(regexp = "^\\d{4}-\\d{2}$") private String periode; // Ex: "2026-03" } ``` #### Validators custom - Implémentation **Annotation** : ```java @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = AmountValidator.class) public @interface ValidAmount { String message() default "Montant invalide"; double min() default 0.0; double max() default Double.MAX_VALUE; Class[] groups() default {}; Class[] payload() default {}; } ``` **Validator** : ```java public class AmountValidator implements ConstraintValidator { private double min; private double max; @Override public void initialize(ValidAmount annotation) { this.min = annotation.min(); this.max = annotation.max(); } @Override public boolean isValid(BigDecimal value, ConstraintValidatorContext context) { if (value == null) return true; // Use @NotNull separately double amount = value.doubleValue(); // Check positive if (amount <= 0) { context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate("Le montant doit être positif") .addConstraintViolation(); return false; } // Check range if (amount < min || amount > max) { context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate( String.format("Le montant doit être entre %.2f et %.2f", min, max) ).addConstraintViolation(); return false; } // Check max 2 decimals if (value.scale() > 2) { context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate("Maximum 2 décimales autorisées") .addConstraintViolation(); return false; } return true; } } ``` ### 3. Enums #### Exemple : StatutApprobation ```java public enum StatutApprobation { PENDING("En attente"), APPROVED("Approuvée"), REJECTED("Rejetée"), CANCELLED("Annulée"); private final String libelle; StatutApprobation(String libelle) { this.libelle = libelle; } public String getLibelle() { return libelle; } public static StatutApprobation fromString(String str) { return Arrays.stream(values()) .filter(s -> s.name().equalsIgnoreCase(str)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Statut invalide: " + str)); } } ``` **Usage** : ```java StatutApprobation statut = StatutApprobation.APPROVED; System.out.println(statut.getLibelle()); // "Approuvée" StatutApprobation parsed = StatutApprobation.fromString("PENDING"); ``` ### 4. BaseResponse - Héritage commun Tous les Response DTOs étendent `BaseResponse` : ```java @Data @NoArgsConstructor public abstract class BaseResponse implements Serializable { private static final long serialVersionUID = 1L; // Audit fields (si nécessaire côté client) private LocalDateTime dateCreation; private LocalDateTime dateModification; private Boolean actif; } ``` **Avantages** : - Champs audit automatiques - Serializable pour cache/sessions - Type-safe avec génériques --- ## 🧪 Tests ### Tests de validation **Fichier** : `src/test/java/dev/lions/unionflow/server/api/validation/AmountValidatorTest.java` ```java @Test void shouldRejectNegativeAmount() { CreatePaiementRequest request = new CreatePaiementRequest(); request.setMontant(BigDecimal.valueOf(-100)); Set> violations = validator.validate(request); assertFalse(violations.isEmpty()); assertTrue(violations.stream() .anyMatch(v -> v.getMessage().contains("positif"))); } @Test void shouldRejectTooManyDecimals() { CreatePaiementRequest request = new CreatePaiementRequest(); request.setMontant(BigDecimal.valueOf(100.123)); Set> violations = validator.validate(request); assertFalse(violations.isEmpty()); assertTrue(violations.stream() .anyMatch(v -> v.getMessage().contains("2 décimales"))); } ``` ### Lancer les tests ```bash mvn test ``` --- ## 📊 DTOs par Feature ### Dashboard - `DashboardStatsResponse` - Stats organisation (membres, cotisations, events) - `MembreDashboardSyntheseResponse` - Synthèse membre (solde, cotisations) - `UpcomingEventResponse` - Événements à venir ### Finance Workflow - `TransactionApprovalResponse` - Approbation de transaction - `BudgetResponse` - Budget avec lignes budgétaires - `AdhesionResponse` - Adhésion membre ### Membres - `MembreResponse` - Détails membre complets - `MembreSummaryResponse` - Résumé membre (liste) - `CreateMembreRequest` - Création membre - `UpdateMembreRequest` - Modification membre ### Cotisations - `CotisationResponse` - Cotisation avec détails - `CreateCotisationRequest` - Enregistrement cotisation - `CotisationStatisticsResponse` - Statistiques cotisations ### Notifications - `NotificationResponse` - Notification utilisateur - `MarkAsReadRequest` - Marquer comme lue --- ## 🔄 Publication Maven (Développeurs seulement) ### Publier une nouvelle version ```bash # 1. Mettre à jour la version dans pom.xml 2.1.0 # 2. Compiler et publier mvn clean deploy # Les artifacts sont publiés sur: # https://git.lions.dev/api/packages/lionsdev/maven ``` ### Versioning Semantic - **Major** (2.0.0) : Breaking changes - **Minor** (2.1.0) : Nouvelles features (backward compatible) - **Patch** (2.0.1) : Bugfixes --- ## 📝 Changelog ### v2.0.0 (2026-03-14) ✅ **Nouveau** : - DTOs Finance Workflow complets - Validation `@ValidAmount` avec min/max - Enums `BudgetPeriod`, `BudgetCategory` - `TransactionApprovalResponse` avec tous les champs ✅ **Améliorations** : - BaseResponse avec audit fields - ValidationConstants centralisées - Javadoc complète pour tous les DTOs ### v1.0.0 (2026-01-04) - Version initiale - 20+ DTOs principaux - 10+ validators custom --- ## 📚 Documentation ### Javadoc ```bash # Générer Javadoc mvn javadoc:javadoc # Ouvrir open target/site/apidocs/index.html ``` ### Ressources - **Jakarta Bean Validation**: https://jakarta.ee/specifications/bean-validation/ - **Maven Repository**: https://git.lions.dev/lionsdev/unionflow-server-api --- ## 🤝 Contribution 1. Créer une branche feature 2. Ajouter DTOs/Validators avec tests 3. Documenter avec Javadoc 4. Pull Request avec description --- ## 📄 Licence Propriétaire - © 2026 Lions Club Côte d'Ivoire --- **Version** : 2.0.0 **Dernière mise à jour** : 2026-03-14 **Auteur** : Équipe UnionFlow