Files
unionflow-server-api/README.md

551 lines
14 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 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>1.0.7</version>
</dependency>
```
> **Version publiée Gitea Maven (2026-04-24)** : `1.0.7` — module autonome (pas de `unionflow-parent`), aligné Quarkus 3.27.3 LTS.
### 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 publiée Gitea Maven** : 1.0.7 (2026-04-24)
**Dernière mise à jour** : 2026-04-24
**Auteur** : Équipe UnionFlow