Files
unionflow-server-impl-quarkus/README.md

591 lines
14 KiB
Markdown

# UnionFlow Backend - API REST Quarkus
![Java](https://img.shields.io/badge/Java-17-blue)
![Quarkus](https://img.shields.io/badge/Quarkus-3.15.1-red)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15-blue)
![Kafka](https://img.shields.io/badge/Kafka-Enabled-orange)
![License](https://img.shields.io/badge/License-Proprietary-red)
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