- docker-compose.dev.yml: retire le service kafka (standalone existant sur :9092), kafka-ui pointe host.docker.internal:9092 - application-dev.properties: OIDC admin-service realm corrigé lions-user-manager (fix AUTH changement mdp) - application-prod.properties: nouvelle var KEYCLOAK_LUM_AUTH_SERVER_URL + fallback KEYCLOAK_CLIENT_SECRET - application.properties: quarkus.flyway.out-of-order=true (évite échec si migration hors-séquence) - V10 renommé V10_1 (évite conflit avec historique Flyway existant) - AlertMonitoringService: guard Arc.container().isRunning() pour éviter NPE au shutdown - TypeOrganisationReferenceResource: forward categorie + modulesRequis au service - Tests: coverage TypeOrganisationReferenceResource + TypeReferenceService
UnionFlow Backend - API REST Quarkus
Backend REST API pour UnionFlow - Gestion des mutuelles, associations et organisations Lions Club.
📋 Table des Matières
- Architecture
- Technologies
- Prérequis
- Installation
- Configuration
- Lancement
- API Documentation
- Base de données
- Kafka Event Streaming
- WebSocket Temps Réel
- Tests
- 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)
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
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 :
<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
# 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
# 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
# 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 :
# 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)
./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
# 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
# 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 attentePOST /api/v1/finance/approvals/{id}/approve- Approuver transactionPOST /api/v1/finance/approvals/{id}/reject- Rejeter transactionGET /api/v1/finance/budgets- Liste des budgetsPOST /api/v1/finance/budgets- Créer budget
Dashboard
GET /api/v1/dashboard/stats- Stats organisationGET /api/v1/dashboard/kpi- KPI temps réelGET /api/v1/dashboard/activities- Activités récentes
Membres
GET /api/v1/membres- Liste membresGET /api/v1/membres/{id}- Détails membrePOST /api/v1/membres- Créer membrePUT /api/v1/membres/{id}- Modifier membre
Cotisations
GET /api/v1/cotisations- Liste cotisationsPOST /api/v1/cotisations- Enregistrer cotisationGET /api/v1/cotisations/member/{memberId}- Cotisations d'un membre
Notifications
GET /api/v1/notifications- Liste notifications userPUT /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, versionOrganisation: nom, type, quotaMembre: nom, prenom, email, telephone, organisationCotisation: membre, montant, periode, statutAdhesion: membre, type, dateDebut, dateFinEvenement: titre, date, lieu, organisationDemandeAide: membre, categorie, montant, statutTransactionApproval: type, montant, statut (PENDING/APPROVED/REJECTED)Budget: nom, periode, année, lignes budgétairesNotification: user, titre, message, lu
Migrations Flyway
Localisation : src/main/resources/db/migration/
V1.0__Initial_Schema.sql- Création tables initialesV2.0__Finance_Workflow.sql- Tables Finance WorkflowV2.1__Add_Indexes.sql- Index performanceV3.0__Kafka_Events.sql- Support event sourcing (futur)
Exécution migrations
# Automatique au démarrage (quarkus.flyway.migrate-at-start=true)
./mvnw quarkus:dev
# Ou manuellement
./mvnw flyway:migrate
Commandes utiles
# 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 approbationsunionflow.dashboard.stats- Stats dashboardunionflow.notifications.user- Notifications utilisateursunionflow.members.events- Événements membresunionflow.contributions.events- Cotisations
Producer Kafka
Classe : KafkaEventProducer
@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 pour l'architecture complète.
🔌 WebSocket Temps Réel
Endpoint
URL : ws://localhost:8085/ws/dashboard
Classe WebSocket
Fichier : DashboardWebSocket.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) :
final channel = WebSocketChannel.connect(
Uri.parse('ws://localhost:8085/ws/dashboard')
);
channel.stream.listen((message) {
print('Event received: $message');
});
🧪 Tests
Lancer les tests
# 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)
# 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 ClusterIPingress.yaml- Ingress HTTPSconfigmap.yaml- Configurationsecret.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
@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
Logger.info("Finance approval created",
kv("approvalId", approval.getId()),
kv("organizationId", orgId),
kv("amount", amount)
);
📝 Contribution
- Fork le projet
- Créer une branche feature (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - 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