# 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` 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 gitea-lionsdev ${env.GITEA_USERNAME} ${env.GITEA_TOKEN} gitea-maven external:* https://git.lions.dev/api/packages/lionsdev/maven ``` ### 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 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