Initial commit: unionflow-server-api
Code source complet à la racine du repository. Signed-off-by: lions dev Team
This commit is contained in:
548
README.md
Normal file
548
README.md
Normal file
@@ -0,0 +1,548 @@
|
||||
# UnionFlow Server API - DTOs et Contrats
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user