Sync: code local unifié
Synchronisation du code source local (fait foi). Signed-off-by: lions dev Team
This commit is contained in:
590
README.md
Normal file
590
README.md
Normal file
@@ -0,0 +1,590 @@
|
||||
# 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_ENTITE, MEMBRE_ACTIF, MEMBRE
|
||||
- **Token** : Bearer token dans header `Authorization`
|
||||
|
||||
### Endpoints protégés
|
||||
|
||||
```java
|
||||
@RolesAllowed({"SUPER_ADMIN", "ADMIN_ENTITE"})
|
||||
@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
|
||||
Reference in New Issue
Block a user