# 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
