Files
unionflow-server-api/README.md

549 lines
14 KiB
Markdown

# 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
<dependency>
<groupId>dev.lions.unionflow</groupId>
<artifactId>unionflow-server-api</artifactId>
<version>2.0.0</version>
</dependency>
```
### Repository Gitea (Maven Registry)
Configurer `~/.m2/settings.xml` :
```xml
<settings>
<servers>
<server>
<id>gitea-lionsdev</id>
<username>${env.GITEA_USERNAME}</username>
<password>${env.GITEA_TOKEN}</password>
</server>
</servers>
<repositories>
<repository>
<id>gitea-lionsdev</id>
<url>https://git.lions.dev/api/packages/lionsdev/maven</url>
</repository>
</repositories>
</settings>
```
### 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<? extends Payload>[] payload() default {};
}
```
**Validator** :
```java
public class AmountValidator implements ConstraintValidator<ValidAmount, BigDecimal> {
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<ConstraintViolation<CreatePaiementRequest>> 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<ConstraintViolation<CreatePaiementRequest>> 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
<version>2.1.0</version>
# 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