Sync: code local unifié
Synchronisation du code source local (fait foi). Signed-off-by: lions dev Team
This commit is contained in:
@@ -4,32 +4,237 @@ import io.quarkus.runtime.Quarkus;
|
||||
import io.quarkus.runtime.QuarkusApplication;
|
||||
import io.quarkus.runtime.annotations.QuarkusMain;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Application principale UnionFlow Server
|
||||
* Point d'entrée principal du serveur UnionFlow.
|
||||
*
|
||||
* @author Lions Dev Team
|
||||
* @version 1.0.0
|
||||
* <p><b>UnionFlow</b> est une plateforme de gestion associative multi-tenant
|
||||
* destinée aux organisations de solidarité (associations, mutuelles, coopératives,
|
||||
* tontines, ONG) en Afrique de l'Ouest.
|
||||
*
|
||||
* <h2>Architecture</h2>
|
||||
* <ul>
|
||||
* <li><b>Backend</b> : Quarkus 3.15.1, Java 17, Hibernate Panache</li>
|
||||
* <li><b>Base de données</b> : PostgreSQL 15 avec Flyway</li>
|
||||
* <li><b>Authentification</b> : Keycloak 23 (OIDC/OAuth2)</li>
|
||||
* <li><b>API</b> : REST (JAX-RS) + WebSocket (temps réel)</li>
|
||||
* <li><b>Paiements</b> : Wave Money CI (Mobile Money)</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Modules fonctionnels</h2>
|
||||
* <ul>
|
||||
* <li><b>Organisations</b> — Hiérarchie multi-niveau, types paramétrables,
|
||||
* modules activables par organisation</li>
|
||||
* <li><b>Membres</b> — Adhésion, profils, rôles/permissions RBAC,
|
||||
* synchronisation bidirectionnelle avec Keycloak</li>
|
||||
* <li><b>Cotisations & Paiements</b> — Campagnes récurrentes,
|
||||
* ventilation polymorphique, intégration Wave Money</li>
|
||||
* <li><b>Événements</b> — Création, inscriptions, gestion des présences,
|
||||
* géolocalisation</li>
|
||||
* <li><b>Solidarité</b> — Demandes d'aide, propositions, matching intelligent,
|
||||
* workflow de validation multi-étapes</li>
|
||||
* <li><b>Mutuelles</b> — Épargne, crédit, tontines, suivi des tours</li>
|
||||
* <li><b>Comptabilité</b> — Plan comptable SYSCOHADA, journaux,
|
||||
* écritures automatiques, balance, grand livre</li>
|
||||
* <li><b>Documents</b> — Gestion polymorphique de pièces jointes
|
||||
* (stockage local + métadonnées)</li>
|
||||
* <li><b>Notifications</b> — Templates multicanaux (email, SMS, push),
|
||||
* préférences utilisateur, historique persistant</li>
|
||||
* <li><b>Analytics & Dashboard</b> — KPIs temps réel via WebSocket,
|
||||
* métriques d'activité, tendances, rapports PDF</li>
|
||||
* <li><b>Administration</b> — Audit trail complet, tickets support,
|
||||
* suggestions utilisateurs, favoris</li>
|
||||
* <li><b>SaaS Multi-tenant</b> — Formules d'abonnement flexibles,
|
||||
* souscriptions par organisation, facturation</li>
|
||||
* <li><b>Configuration dynamique</b> — Table {@code configurations},
|
||||
* pas de hardcoding, paramétrage par organisation</li>
|
||||
* <li><b>Données de référence</b> — Table {@code types_reference}
|
||||
* entièrement CRUD-able (évite les enums Java)</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Inventaire technique</h2>
|
||||
* <ul>
|
||||
* <li><b>60 entités JPA</b> — {@code BaseEntity} + {@code AuditEntityListener}
|
||||
* pour audit automatique</li>
|
||||
* <li><b>46 services CDI</b> — Logique métier transactionnelle</li>
|
||||
* <li><b>37 endpoints REST</b> — API JAX-RS avec validation Bean Validation</li>
|
||||
* <li><b>49 repositories</b> — Hibernate Panache pour accès données</li>
|
||||
* <li><b>Migrations Flyway</b> — V1.0 --> V3.0 (schéma complet 60 tables)</li>
|
||||
* <li><b>Tests</b> — 1127 tests unitaires et d'intégration Quarkus</li>
|
||||
* <li><b>Couverture</b> — JaCoCo 40% minimum (cible 60%)</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Patterns et Best Practices</h2>
|
||||
* <ul>
|
||||
* <li><b>Clean Architecture</b> — Séparation API/Impl/Entity</li>
|
||||
* <li><b>DTO Pattern</b> — Request/Response distincts (142 DTOs dans server-api)</li>
|
||||
* <li><b>Repository Pattern</b> — Abstraction accès données</li>
|
||||
* <li><b>Service Layer</b> — Transactionnel, validation métier</li>
|
||||
* <li><b>Audit automatique</b> — EntityListener JPA pour traçabilité complète</li>
|
||||
* <li><b>Soft Delete</b> — Champ {@code actif} sur toutes les entités</li>
|
||||
* <li><b>Optimistic Locking</b> — Champ {@code version} pour concurrence</li>
|
||||
* <li><b>Configuration externalisée</b> — MicroProfile Config, pas de hardcoding</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Sécurité</h2>
|
||||
* <ul>
|
||||
* <li>OIDC avec Keycloak (realm: unionflow)</li>
|
||||
* <li>JWT signature côté backend (HMAC-SHA256)</li>
|
||||
* <li>RBAC avec rôles: SUPER_ADMIN, ADMIN_ENTITE, MEMBRE</li>
|
||||
* <li>Permissions granulaires par module</li>
|
||||
* <li>CORS configuré pour client web</li>
|
||||
* <li>HTTPS obligatoire en production</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author UnionFlow Team
|
||||
* @version 3.0.0
|
||||
* @since 2025-01-29
|
||||
*/
|
||||
@QuarkusMain
|
||||
@ApplicationScoped
|
||||
public class UnionFlowServerApplication implements QuarkusApplication {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(UnionFlowServerApplication.class);
|
||||
private static final Logger LOG = Logger.getLogger(UnionFlowServerApplication.class);
|
||||
|
||||
public static void main(String... args) {
|
||||
Quarkus.run(UnionFlowServerApplication.class, args);
|
||||
}
|
||||
/** Port HTTP configuré (défaut: 8080). */
|
||||
@ConfigProperty(name = "quarkus.http.port", defaultValue = "8080")
|
||||
int httpPort;
|
||||
|
||||
@Override
|
||||
public int run(String... args) throws Exception {
|
||||
LOG.info("🚀 UnionFlow Server démarré avec succès!");
|
||||
LOG.info("📊 API disponible sur http://localhost:8080");
|
||||
LOG.info("📖 Documentation OpenAPI sur http://localhost:8080/q/swagger-ui");
|
||||
LOG.info("💚 Health check sur http://localhost:8080/health");
|
||||
/** Host HTTP configuré (défaut: 0.0.0.0). */
|
||||
@ConfigProperty(name = "quarkus.http.host", defaultValue = "0.0.0.0")
|
||||
String httpHost;
|
||||
|
||||
Quarkus.waitForExit();
|
||||
return 0;
|
||||
}
|
||||
/** Nom de l'application. */
|
||||
@ConfigProperty(name = "quarkus.application.name", defaultValue = "unionflow-server")
|
||||
String applicationName;
|
||||
|
||||
/** Version de l'application. */
|
||||
@ConfigProperty(name = "quarkus.application.version", defaultValue = "3.0.0")
|
||||
String applicationVersion;
|
||||
|
||||
/** Profil actif (dev, test, prod). */
|
||||
@ConfigProperty(name = "quarkus.profile")
|
||||
String activeProfile;
|
||||
|
||||
/** Version de Quarkus. */
|
||||
@ConfigProperty(name = "quarkus.platform.version", defaultValue = "3.15.1")
|
||||
String quarkusVersion;
|
||||
|
||||
/**
|
||||
* Point d'entrée JVM.
|
||||
*
|
||||
* <p>Lance l'application Quarkus en mode bloquant.
|
||||
* En mode natif, cette méthode démarre instantanément (< 50ms).
|
||||
*
|
||||
* @param args Arguments de ligne de commande (non utilisés)
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
Quarkus.run(UnionFlowServerApplication.class, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de démarrage de l'application.
|
||||
*
|
||||
* <p>Affiche les informations de démarrage (URLs, configuration)
|
||||
* puis attend le signal d'arrêt (SIGTERM, SIGINT).
|
||||
*
|
||||
* @param args Arguments passés depuis main()
|
||||
* @return Code de sortie (0 = succès)
|
||||
* @throws Exception Si erreur fatale au démarrage
|
||||
*/
|
||||
@Override
|
||||
public int run(String... args) throws Exception {
|
||||
logStartupBanner();
|
||||
logConfiguration();
|
||||
logEndpoints();
|
||||
logArchitecture();
|
||||
|
||||
LOG.info("UnionFlow Server prêt à recevoir des requêtes");
|
||||
LOG.info("Appuyez sur Ctrl+C pour arrêter");
|
||||
|
||||
// Attend le signal d'arrêt (bloquant)
|
||||
Quarkus.waitForExit();
|
||||
|
||||
LOG.info("UnionFlow Server arrêté proprement");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche la bannière ASCII de démarrage.
|
||||
*/
|
||||
private void logStartupBanner() {
|
||||
LOG.info("----------------------------------------------------------");
|
||||
LOG.info("- -");
|
||||
LOG.info("- UNIONFLOW SERVER v" + applicationVersion + " ");
|
||||
LOG.info("- Plateforme de Gestion Associative Multi-Tenant -");
|
||||
LOG.info("- -");
|
||||
LOG.info("----------------------------------------------------------");
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche la configuration active.
|
||||
*/
|
||||
private void logConfiguration() {
|
||||
LOG.infof("Profil : %s", activeProfile);
|
||||
LOG.infof("Application : %s v%s", applicationName, applicationVersion);
|
||||
LOG.infof("Java : %s", System.getProperty("java.version"));
|
||||
LOG.infof("Quarkus : %s", quarkusVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche les URLs des endpoints principaux.
|
||||
*/
|
||||
private void logEndpoints() {
|
||||
String baseUrl = buildBaseUrl();
|
||||
|
||||
LOG.info("--------------------------------------------------------------");
|
||||
LOG.info("📡 Endpoints disponibles:");
|
||||
LOG.infof(" - API REST --> %s/api", baseUrl);
|
||||
LOG.infof(" - Swagger UI --> %s/q/swagger-ui", baseUrl);
|
||||
LOG.infof(" - Health Check --> %s/q/health", baseUrl);
|
||||
LOG.infof(" - Metrics --> %s/q/metrics", baseUrl);
|
||||
LOG.infof(" - OpenAPI --> %s/q/openapi", baseUrl);
|
||||
|
||||
if ("dev".equals(activeProfile)) {
|
||||
LOG.infof(" - Dev UI --> %s/q/dev", baseUrl);
|
||||
LOG.infof(" - H2 Console --> %s/q/dev/io.quarkus.quarkus-datasource/datasources", baseUrl);
|
||||
}
|
||||
|
||||
LOG.info("--------------------------------------------------------------");
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche l'inventaire de l'architecture.
|
||||
*/
|
||||
private void logArchitecture() {
|
||||
LOG.info(" Architecture:");
|
||||
LOG.info(" - 60 Entités JPA");
|
||||
LOG.info(" - 46 Services CDI");
|
||||
LOG.info(" - 37 Endpoints REST");
|
||||
LOG.info(" - 49 Repositories Panache");
|
||||
LOG.info(" - 142 DTOs (Request/Response)");
|
||||
LOG.info(" - 1127 Tests automatisés");
|
||||
LOG.info("--------------------------------------------------------------");
|
||||
}
|
||||
|
||||
/**
|
||||
* Construit l'URL de base de l'application.
|
||||
*
|
||||
* @return URL complète (ex: http://localhost:8080)
|
||||
*/
|
||||
private String buildBaseUrl() {
|
||||
// En production, utiliser le nom de domaine configuré
|
||||
if ("prod".equals(activeProfile)) {
|
||||
String domain = System.getenv("UNIONFLOW_DOMAIN");
|
||||
if (domain != null && !domain.isEmpty()) {
|
||||
return "https://" + domain;
|
||||
}
|
||||
}
|
||||
|
||||
// En dev/test, utiliser localhost
|
||||
String host = "0.0.0.0".equals(httpHost) ? "localhost" : httpHost;
|
||||
return String.format("http://%s:%d", host, httpPort);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user