591 lines
14 KiB
Markdown
591 lines
14 KiB
Markdown
# UnionFlow Backend - API REST Quarkus
|
|
|
|

|
|

|
|

|
|

|
|

|
|
|
|
Backend REST API pour UnionFlow - Gestion des mutuelles, associations et organisations Lions Club.
|
|
|
|
---
|
|
|
|
## 📋 Table des Matières
|
|
|
|
- [Architecture](#architecture)
|
|
- [Technologies](#technologies)
|
|
- [Prérequis](#prérequis)
|
|
- [Installation](#installation)
|
|
- [Configuration](#configuration)
|
|
- [Lancement](#lancement)
|
|
- [API Documentation](#api-documentation)
|
|
- [Base de données](#base-de-données)
|
|
- [Kafka Event Streaming](#kafka-event-streaming)
|
|
- [WebSocket Temps Réel](#websocket-temps-réel)
|
|
- [Tests](#tests)
|
|
- [Déploiement](#déploiement)
|
|
|
|
---
|
|
|
|
## 🏗️ Architecture
|
|
|
|
### Clean Architecture + DDD
|
|
|
|
```
|
|
src/main/java/dev/lions/unionflow/
|
|
├── domain/ # Domain Layer (Entities métier)
|
|
│ ├── entities/ # Entités JPA (37 entités)
|
|
│ └── repositories/ # Repositories Panache
|
|
├── application/ # Application Layer (Use Cases)
|
|
│ └── services/ # Services métier
|
|
├── infrastructure/ # Infrastructure Layer
|
|
│ ├── rest/ # REST Controllers
|
|
│ ├── messaging/ # Kafka Producers
|
|
│ ├── websocket/ # WebSocket endpoints
|
|
│ └── persistence/ # Configuration JPA
|
|
└── shared/ # Shared Kernel
|
|
├── dto/ # DTOs (Request/Response)
|
|
├── exceptions/ # Custom exceptions
|
|
└── mappers/ # MapStruct mappers
|
|
```
|
|
|
|
### Pattern Repository avec Panache
|
|
|
|
Tous les repositories étendent `PanacheRepositoryBase<Entity, UUID>` pour :
|
|
- CRUD automatique
|
|
- Queries typées
|
|
- Streaming support
|
|
- Active Record pattern (optionnel)
|
|
|
|
---
|
|
|
|
## 🛠️ Technologies
|
|
|
|
| Composant | Version | Usage |
|
|
|-----------|---------|-------|
|
|
| **Java** | 17 (LTS) | Langage |
|
|
| **Quarkus** | 3.15.1 | Framework application |
|
|
| **Hibernate ORM (Panache)** | 6.4+ | Persistence |
|
|
| **PostgreSQL** | 15 | Base de données |
|
|
| **Flyway** | 9.22+ | Migrations DB |
|
|
| **Kafka** | SmallRye Reactive Messaging | Event streaming |
|
|
| **WebSocket** | Quarkus WebSockets Next | Temps réel |
|
|
| **Keycloak** | OIDC/JWT | Authentification |
|
|
| **OpenPDF** | 1.3.30 | Export PDF |
|
|
| **MapStruct** | 1.5+ | Mapping DTO ↔ Entity |
|
|
| **Lombok** | 1.18.34 | Réduction boilerplate |
|
|
| **RESTEasy** | Reactive | REST endpoints |
|
|
| **SmallRye Health** | - | Health checks |
|
|
| **SmallRye OpenAPI** | - | Documentation API |
|
|
|
|
---
|
|
|
|
## 📦 Prérequis
|
|
|
|
### Environnement de développement
|
|
|
|
- **Java Development Kit**: OpenJDK 17 ou supérieur
|
|
- **Maven**: 3.8+
|
|
- **Docker**: 20.10+ (pour PostgreSQL, Keycloak, Kafka)
|
|
- **Git**: 2.30+
|
|
|
|
### Services externes (via Docker Compose)
|
|
|
|
```bash
|
|
cd unionflow/
|
|
docker-compose up -d
|
|
```
|
|
|
|
Services démarrés :
|
|
- **PostgreSQL** : `localhost:5432` (DB: `unionflow`, user: `unionflow`, pass: `unionflow`)
|
|
- **Keycloak** : `localhost:8180` (realm: `unionflow`, client: `unionflow-mobile`)
|
|
- **Kafka** : `localhost:9092` (topics auto-créés)
|
|
- **Zookeeper** : `localhost:2181`
|
|
- **MailDev** : `localhost:1080` (SMTP testing)
|
|
|
|
---
|
|
|
|
## 🚀 Installation
|
|
|
|
### 1. Cloner le projet
|
|
|
|
```bash
|
|
git clone https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus.git
|
|
cd unionflow-server-impl-quarkus
|
|
```
|
|
|
|
### 2. Configurer Maven
|
|
|
|
Ajouter le repository Gitea à `~/.m2/settings.xml` :
|
|
|
|
```xml
|
|
<settings>
|
|
<servers>
|
|
<server>
|
|
<id>gitea-lionsdev</id>
|
|
<username>${env.GITEA_USERNAME}</username>
|
|
<password>${env.GITEA_TOKEN}</password>
|
|
</server>
|
|
</servers>
|
|
|
|
<mirrors>
|
|
<mirror>
|
|
<id>gitea-maven</id>
|
|
<mirrorOf>external:*</mirrorOf>
|
|
<url>https://git.lions.dev/api/packages/lionsdev/maven</url>
|
|
</mirror>
|
|
</mirrors>
|
|
</settings>
|
|
```
|
|
|
|
### 3. Compiler
|
|
|
|
```bash
|
|
# Compilation standard
|
|
./mvnw clean package
|
|
|
|
# Sans tests (rapide)
|
|
./mvnw clean package -DskipTests
|
|
|
|
# Avec profil production
|
|
./mvnw clean package -Pproduction
|
|
```
|
|
|
|
---
|
|
|
|
## ⚙️ Configuration
|
|
|
|
### Variables d'environnement
|
|
|
|
#### Développement
|
|
|
|
```bash
|
|
# Base de données
|
|
export DB_URL=jdbc:postgresql://localhost:5432/unionflow
|
|
export DB_USERNAME=unionflow
|
|
export DB_PASSWORD=unionflow
|
|
|
|
# Keycloak
|
|
export KEYCLOAK_URL=http://localhost:8180/realms/unionflow
|
|
export KEYCLOAK_CLIENT_SECRET=votre-secret-dev
|
|
|
|
# Kafka
|
|
export KAFKA_BOOTSTRAP_SERVERS=localhost:9092
|
|
```
|
|
|
|
#### Production
|
|
|
|
```bash
|
|
# Base de données
|
|
export DB_URL=jdbc:postgresql://postgresql-service.postgresql.svc.cluster.local:5432/unionflow
|
|
export DB_USERNAME=unionflow
|
|
export DB_PASSWORD=${SECURE_DB_PASSWORD}
|
|
|
|
# Keycloak
|
|
export KEYCLOAK_URL=https://security.lions.dev/realms/unionflow
|
|
export KEYCLOAK_CLIENT_SECRET=${SECURE_CLIENT_SECRET}
|
|
|
|
# Kafka
|
|
export KAFKA_BOOTSTRAP_SERVERS=kafka-service.kafka.svc.cluster.local:9092
|
|
|
|
# CORS
|
|
export CORS_ORIGINS=https://unionflow.lions.dev,https://api.lions.dev
|
|
```
|
|
|
|
### application.properties
|
|
|
|
**Dev** : `src/main/resources/application.properties`
|
|
**Prod** : `src/main/resources/application-prod.properties`
|
|
|
|
Propriétés clés :
|
|
```properties
|
|
# HTTP
|
|
quarkus.http.port=8085
|
|
quarkus.http.cors.origins=http://localhost:3000,http://localhost:8086
|
|
|
|
# Database
|
|
quarkus.datasource.db-kind=postgresql
|
|
quarkus.hibernate-orm.database.generation=validate # Production
|
|
quarkus.flyway.migrate-at-start=true
|
|
|
|
# Keycloak OIDC
|
|
quarkus.oidc.auth-server-url=${KEYCLOAK_URL}
|
|
quarkus.oidc.client-id=unionflow-backend
|
|
quarkus.oidc.credentials.secret=${KEYCLOAK_CLIENT_SECRET}
|
|
|
|
# Kafka
|
|
kafka.bootstrap.servers=${KAFKA_BOOTSTRAP_SERVERS:localhost:9092}
|
|
mp.messaging.outgoing.finance-approvals.connector=smallrye-kafka
|
|
|
|
# WebSocket
|
|
quarkus.websockets.enabled=true
|
|
```
|
|
|
|
---
|
|
|
|
## 🏃 Lancement
|
|
|
|
### Mode développement (Live Reload)
|
|
|
|
```bash
|
|
./mvnw quarkus:dev
|
|
|
|
# Accès
|
|
# - API: http://localhost:8085
|
|
# - Swagger UI: http://localhost:8085/q/swagger-ui
|
|
# - Health: http://localhost:8085/q/health
|
|
# - Dev UI: http://localhost:8085/q/dev
|
|
```
|
|
|
|
### Mode production
|
|
|
|
```bash
|
|
# Build
|
|
./mvnw clean package -Pproduction
|
|
|
|
# Run
|
|
java -jar target/quarkus-app/quarkus-run.jar
|
|
|
|
# Ou avec profil spécifique
|
|
java -Dquarkus.profile=prod -jar target/quarkus-app/quarkus-run.jar
|
|
```
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
# Build image
|
|
docker build -f src/main/docker/Dockerfile.jvm -t unionflow-backend:latest .
|
|
|
|
# Run container
|
|
docker run -p 8085:8085 \
|
|
-e DB_URL=jdbc:postgresql://host.docker.internal:5432/unionflow \
|
|
-e DB_USERNAME=unionflow \
|
|
-e DB_PASSWORD=unionflow \
|
|
-e KEYCLOAK_CLIENT_SECRET=secret \
|
|
unionflow-backend:latest
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 API Documentation
|
|
|
|
### Swagger UI
|
|
|
|
**Dev** : http://localhost:8085/q/swagger-ui
|
|
**Prod** : https://api.lions.dev/unionflow/q/swagger-ui
|
|
|
|
### Endpoints principaux
|
|
|
|
#### Finance Workflow
|
|
|
|
- `GET /api/v1/finance/approvals` - Liste des approbations en attente
|
|
- `POST /api/v1/finance/approvals/{id}/approve` - Approuver transaction
|
|
- `POST /api/v1/finance/approvals/{id}/reject` - Rejeter transaction
|
|
- `GET /api/v1/finance/budgets` - Liste des budgets
|
|
- `POST /api/v1/finance/budgets` - Créer budget
|
|
|
|
#### Dashboard
|
|
|
|
- `GET /api/v1/dashboard/stats` - Stats organisation
|
|
- `GET /api/v1/dashboard/kpi` - KPI temps réel
|
|
- `GET /api/v1/dashboard/activities` - Activités récentes
|
|
|
|
#### Membres
|
|
|
|
- `GET /api/v1/membres` - Liste membres
|
|
- `GET /api/v1/membres/{id}` - Détails membre
|
|
- `POST /api/v1/membres` - Créer membre
|
|
- `PUT /api/v1/membres/{id}` - Modifier membre
|
|
|
|
#### Cotisations
|
|
|
|
- `GET /api/v1/cotisations` - Liste cotisations
|
|
- `POST /api/v1/cotisations` - Enregistrer cotisation
|
|
- `GET /api/v1/cotisations/member/{memberId}` - Cotisations d'un membre
|
|
|
|
#### Notifications
|
|
|
|
- `GET /api/v1/notifications` - Liste notifications user
|
|
- `PUT /api/v1/notifications/{id}/read` - Marquer comme lue
|
|
|
|
---
|
|
|
|
## 🗄️ Base de données
|
|
|
|
### Schéma - 37 Entités
|
|
|
|
**Entités principales** :
|
|
- `BaseEntity` (classe abstraite) : id (UUID), dateCreation, dateModification, actif, version
|
|
- `Organisation` : nom, type, quota
|
|
- `Membre` : nom, prenom, email, telephone, organisation
|
|
- `Cotisation` : membre, montant, periode, statut
|
|
- `Adhesion` : membre, type, dateDebut, dateFin
|
|
- `Evenement` : titre, date, lieu, organisation
|
|
- `DemandeAide` : membre, categorie, montant, statut
|
|
- `TransactionApproval` : type, montant, statut (PENDING/APPROVED/REJECTED)
|
|
- `Budget` : nom, periode, année, lignes budgétaires
|
|
- `Notification` : user, titre, message, lu
|
|
|
|
### Migrations Flyway
|
|
|
|
**Localisation** : `src/main/resources/db/migration/`
|
|
|
|
- `V1.0__Initial_Schema.sql` - Création tables initiales
|
|
- `V2.0__Finance_Workflow.sql` - Tables Finance Workflow
|
|
- `V2.1__Add_Indexes.sql` - Index performance
|
|
- `V3.0__Kafka_Events.sql` - Support event sourcing (futur)
|
|
|
|
### Exécution migrations
|
|
|
|
```bash
|
|
# Automatique au démarrage (quarkus.flyway.migrate-at-start=true)
|
|
./mvnw quarkus:dev
|
|
|
|
# Ou manuellement
|
|
./mvnw flyway:migrate
|
|
```
|
|
|
|
### Commandes utiles
|
|
|
|
```bash
|
|
# Info migrations
|
|
./mvnw flyway:info
|
|
|
|
# Repair (en cas d'erreur)
|
|
./mvnw flyway:repair
|
|
|
|
# Baseline (migration existante DB)
|
|
./mvnw flyway:baseline
|
|
```
|
|
|
|
---
|
|
|
|
## 📡 Kafka Event Streaming
|
|
|
|
### Topics configurés
|
|
|
|
- `unionflow.finance.approvals` - Workflow approbations
|
|
- `unionflow.dashboard.stats` - Stats dashboard
|
|
- `unionflow.notifications.user` - Notifications utilisateurs
|
|
- `unionflow.members.events` - Événements membres
|
|
- `unionflow.contributions.events` - Cotisations
|
|
|
|
### Producer Kafka
|
|
|
|
**Classe** : `KafkaEventProducer`
|
|
|
|
```java
|
|
@ApplicationScoped
|
|
public class KafkaEventProducer {
|
|
|
|
@Channel("finance-approvals")
|
|
Emitter<String> financeEmitter;
|
|
|
|
public void publishApprovalPending(TransactionApproval approval) {
|
|
var event = Map.of(
|
|
"eventType", "APPROVAL_PENDING",
|
|
"timestamp", Instant.now().toString(),
|
|
"approval", toDTO(approval)
|
|
);
|
|
financeEmitter.send(toJson(event));
|
|
}
|
|
}
|
|
```
|
|
|
|
Voir [KAFKA_WEBSOCKET_ARCHITECTURE.md](../docs/KAFKA_WEBSOCKET_ARCHITECTURE.md) pour l'architecture complète.
|
|
|
|
---
|
|
|
|
## 🔌 WebSocket Temps Réel
|
|
|
|
### Endpoint
|
|
|
|
**URL** : `ws://localhost:8085/ws/dashboard`
|
|
|
|
### Classe WebSocket
|
|
|
|
**Fichier** : `DashboardWebSocket.java`
|
|
|
|
```java
|
|
@ServerEndpoint("/ws/dashboard")
|
|
@ApplicationScoped
|
|
public class DashboardWebSocket {
|
|
|
|
@OnOpen
|
|
public void onOpen(Session session) {
|
|
sessions.add(session);
|
|
}
|
|
|
|
@Incoming("finance-approvals")
|
|
public void handleFinanceEvent(String event) {
|
|
broadcast(event); // Broadcast à tous les clients connectés
|
|
}
|
|
}
|
|
```
|
|
|
|
**Connexion mobile (Flutter)** :
|
|
|
|
```dart
|
|
final channel = WebSocketChannel.connect(
|
|
Uri.parse('ws://localhost:8085/ws/dashboard')
|
|
);
|
|
channel.stream.listen((message) {
|
|
print('Event received: $message');
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## 🧪 Tests
|
|
|
|
### Lancer les tests
|
|
|
|
```bash
|
|
# Tous les tests
|
|
./mvnw test
|
|
|
|
# Tests unitaires seulement
|
|
./mvnw test -Dtest="*Test"
|
|
|
|
# Tests d'intégration seulement
|
|
./mvnw test -Dtest="*IT"
|
|
|
|
# Avec couverture
|
|
./mvnw test jacoco:report
|
|
```
|
|
|
|
### Structure tests
|
|
|
|
```
|
|
src/test/java/
|
|
├── domain/
|
|
│ └── entities/
|
|
│ └── MembreTest.java
|
|
├── application/
|
|
│ └── services/
|
|
│ └── FinanceWorkflowServiceTest.java
|
|
└── infrastructure/
|
|
└── rest/
|
|
└── FinanceResourceIT.java
|
|
```
|
|
|
|
---
|
|
|
|
## 🚢 Déploiement
|
|
|
|
### Kubernetes (Production)
|
|
|
|
**Outil** : `lionsctl` (CLI Go custom)
|
|
|
|
```bash
|
|
# Déploiement complet
|
|
lionsctl pipeline \
|
|
-u https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus \
|
|
-b main \
|
|
-j 17 \
|
|
-e production \
|
|
-c k1 \
|
|
-p prod
|
|
|
|
# Étapes :
|
|
# 1. Clone repo Git
|
|
# 2. mvn clean package -Pprod
|
|
# 3. docker build + push registry.lions.dev
|
|
# 4. kubectl apply -f k8s/
|
|
# 5. Health check
|
|
# 6. Email notification
|
|
```
|
|
|
|
### Fichiers Kubernetes
|
|
|
|
**Localisation** : `src/main/kubernetes/`
|
|
|
|
- `deployment.yaml` - Deployment (3 replicas)
|
|
- `service.yaml` - Service ClusterIP
|
|
- `ingress.yaml` - Ingress HTTPS
|
|
- `configmap.yaml` - Configuration
|
|
- `secret.yaml` - Secrets (DB, Keycloak)
|
|
|
|
### Accès production
|
|
|
|
- **API** : https://api.lions.dev/unionflow
|
|
- **Swagger** : https://api.lions.dev/unionflow/q/swagger-ui
|
|
- **Health** : https://api.lions.dev/unionflow/q/health
|
|
|
|
---
|
|
|
|
## 🔒 Sécurité
|
|
|
|
### Authentification
|
|
|
|
- **Méthode** : OIDC/JWT via Keycloak
|
|
- **Rôles** : SUPER_ADMIN, ADMIN_ORGANISATION, MEMBRE_ACTIF, MEMBRE
|
|
- **Token** : Bearer token dans header `Authorization`
|
|
|
|
### Endpoints protégés
|
|
|
|
```java
|
|
@RolesAllowed({"SUPER_ADMIN", "ADMIN_ORGANISATION"})
|
|
@POST
|
|
@Path("/budgets")
|
|
public Response createBudget(BudgetRequest request) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
### CORS
|
|
|
|
Production : CORS configuré pour `https://unionflow.lions.dev`
|
|
|
|
---
|
|
|
|
## 📊 Monitoring
|
|
|
|
### Health Checks
|
|
|
|
- **Liveness** : `GET /q/health/live`
|
|
- **Readiness** : `GET /q/health/ready`
|
|
|
|
### Metrics (Prometheus-compatible)
|
|
|
|
- **Endpoint** : `GET /q/metrics`
|
|
|
|
### Logs structurés
|
|
|
|
```java
|
|
Logger.info("Finance approval created",
|
|
kv("approvalId", approval.getId()),
|
|
kv("organizationId", orgId),
|
|
kv("amount", amount)
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Contribution
|
|
|
|
1. Fork le projet
|
|
2. Créer une branche feature (`git checkout -b feature/AmazingFeature`)
|
|
3. Commit changes (`git commit -m 'Add AmazingFeature'`)
|
|
4. Push to branch (`git push origin feature/AmazingFeature`)
|
|
5. Ouvrir une Pull Request
|
|
|
|
---
|
|
|
|
## 📄 Licence
|
|
|
|
Propriétaire - © 2026 Lions Club Côte d'Ivoire - Tous droits réservés
|
|
|
|
---
|
|
|
|
## 📞 Support
|
|
|
|
- **Email** : support@lions.dev
|
|
- **Issue Tracker** : https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus/issues
|
|
|
|
---
|
|
|
|
**Version** : 2.0.0
|
|
**Dernière mise à jour** : 2026-03-14
|
|
**Auteur** : Équipe UnionFlow
|