Commit Graph

112 Commits

Author SHA1 Message Date
dahoud
07302f2743 fix(sprint-17 backend): désactivation globale DevServices en test (H2 + OIDC off → aucun container nécessaire)
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m11s
Suite à observation que le précédent fix ciblé `quarkus.keycloak.devservices.enabled=false`
n'empêchait pas le démarrage du container KC (probablement timing build-time vs runtime).

Mode test :
- DataSource : H2 in-memory (lignes 5-8 application-test.properties — pas de Postgres needed)
- OIDC : tenant-enabled=false (pas de KC needed)

Conclusion : aucun DevService nécessaire en test → désactivation globale via
`quarkus.devservices.enabled=false` (couvre tous les services) + garde
`quarkus.keycloak.devservices.enabled=false` en sécurité.

Bénéfice : tests démarrent en 5-10s au lieu de 1-3min (boot containers KC + ryuk).
Mode `quarkus:dev` reste full DevServices (logique, on a besoin de KC en dev).
2026-04-25 17:47:59 +00:00
dahoud
af8d237d01 fix(sprint-17 backend): désactiver Keycloak DevServices en test (OIDC déjà off → KC inutile)
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m9s
Erreur observée :
  ERROR [io.qu.de.ke.KeycloakDevServicesProcessor] Admin token can not be acquired
  due to a client connection timeout
  (~50s boot Docker + timeouts admin token)

Cause : @QuarkusTest charge application-test.properties qui désactive OIDC
(tenant-enabled=false), mais l'extension quarkus-keycloak-* déclenche quand même
le DevService Keycloak qui télécharge/démarre un container KC 26.3.4 et tente
d'obtenir un admin token — qui timeout.

Fix non-appauvrissant : désactiver UNIQUEMENT le DevService KC en mode test.
- Dev mode : DevServices KC reste actif (utile pour quarkus:dev)
- Test mode : OIDC déjà désactivé → KC DevServices = pure perte de temps de boot
- Postgres DevServices reste actif (Hibernate a besoin d'une DB pour les tests JPA)

Ajout :
  quarkus.keycloak.devservices.enabled=false  (test-only via application-test.properties)
2026-04-25 17:34:05 +00:00
dahoud
d52b0f6f2b fix(sprint-17 backend): JwtPropagationFilter @ApplicationScoped — découverte CDI pour @QuarkusTest
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m11s
JwtPropagationFilterTest @QuarkusTest fait @Inject JwtPropagationFilter mais la
classe n'avait aucun scope CDI → UnsatisfiedResolutionException au démarrage du test.

Le commentaire interdisait @Provider (auto-register JAX-RS global qui écraserait le
service account des AdminUserServiceClient/AdminRoleServiceClient). Mais ne disait
rien contre @ApplicationScoped : c'est un scope CDI ≠ provider JAX-RS.

Fix : ajouter @ApplicationScoped (rend découvrable par CDI mais ne provoque PAS
d'enregistrement automatique JAX-RS — l'opt-in reste via @RegisterProvider explicite).
Suppression de l'import jakarta.ws.rs.ext.Provider devenu inutile.

Commentaire de classe enrichi pour clarifier la nuance scope-CDI vs provider-JAX-RS.
2026-04-25 17:21:42 +00:00
dahoud
2826d75aa6 fix(sprint-17 backend): 3 warnings build/dev — Qute -parameters, compiler version, policy-enforcer deprecation
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m52s
3 fixes pour build dev mode propre :

1. Qute @CheckedTemplate (EmailTemplateService.Templates) cassait au démarrage
   → maven-compiler-plugin <parameters>true</parameters> (noms params en bytecode)

2. Maven warning "build.plugins.plugin.version missing"
   → ajout <version>3.13.0</version> au compiler-plugin (cohérent avec api module)

3. Quarkus runtime warning "quarkus.keycloak.policy-enforcer.enable is deprecated"
   → renommé en policy-enforcer.enabled dans application.properties + application-test.properties
   (depuis Quarkus 3.x, propriété renommée pour cohérence avec autres flags enabled)
2026-04-25 17:14:51 +00:00
dahoud
0e264b3c1f fix(sprint-17 backend): KpiShareTokenService.DEFAULT_TTL_SECONDS public (referenced from KpiShareLinkResource in different package)
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m44s
2026-04-25 17:01:54 +00:00
dahoud
ed0d74e124 feat(sprint-17 backend 2026-04-25): Public KPI Sharing — token signé HMAC-SHA256 + endpoints admin/public
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m3s
Transparency réglementaire (Sprint 16.D différé livré en S17). Permet aux autorités
externes (BCEAO, ARTCI, CENTIF, contrôleurs UEMOA) de consulter les KPI agrégés
d'une organisation sans login, via lien signé temporairement.

Architecture sécurité
- KpiShareTokenService : HMAC-SHA256 + base64url, format orgId.expiryMillis.signature
- Vérification time-constant via MessageDigest.isEqual (résistant timing attacks)
- Secret @ConfigProperty unionflow.kpi.share.secret (défaut TTL 7 jours)
- Pas de DB — token autosuffisant, révocable seulement par rotation du secret

KpiPublicService
- snapshotPublic(orgId) : extrait sous-ensemble safe de ComplianceSnapshot
- Audit chaque accès public (méta-traçabilité — qui/quand consulté quoi)

Endpoints
- GET /api/admin/kpi/share-link/{orgId}?ttlSeconds=...
  @RolesAllowed ADMIN_ORGANISATION, PRESIDENT, COMPLIANCE_OFFICER, SUPER_ADMIN
  Retourne {token, ttlSeconds, publicUrl, publicWebPath}
- GET /api/public/kpi?token=...
  @PermitAll (whitelist /api/public/* dans application.properties)
  Retourne KpiPublicSnapshot ou 401/404 si token invalide/expiré ou org introuvable

Bump dépendance api 1.0.9 → 1.0.10 (DTO KpiPublicSnapshot ajouté)

Tests KpiShareTokenService (9 tests)
- Round-trip orgId, ttl 0/<=0 défaut, orgId null exception
- Token expiré (signature fake), tampering signature, tampering orgId
- Malformé (< 3 parts, > 4 parts)
- Null/blank
- Encode/decode round-trip avec caractères spéciaux

ACTION USER : mvn install api 1.0.10 puis tester impl/web.
2026-04-25 16:48:47 +00:00
dahoud
0c46d9bad6 feat(sprint-16 backend 2026-04-25): transparency operations — Métriques Prometheus + Export multi-format + Notifications auto
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m35s
Trois piliers transparency opérationnelle UnionFlow livrés en série :

S16.A — Métriques Prometheus métier (transparency observabilité)
- AuditTrailService.log() incrémente :
  - unionflow.audit.operations{action, entity}
  - unionflow.audit.sod_violations{entity}
- application.properties : quarkus.micrometer.export.prometheus.enabled=true,
  http-server + jvm binders activés
- Endpoint /q/metrics exposé pour scraping Prometheus K8s

S16.B — Export massif audit-trail (transparency réglementaire BCEAO/ARTCI/CENTIF)
- AuditTrailExportService :
  - exportCsv : Apache Commons CSV avec BOM UTF-8 (compat Excel)
  - exportXlsx : POI XSSFWorkbook avec header coloré et auto-size
  - exportPdf : OpenPDF A4 paysage avec table 7 colonnes
- Endpoint GET /api/audit-trail/export?format=csv|xlsx|pdf&scope=...&limit=500
- @RolesAllowed COMPLIANCE_OFFICER, CONTROLEUR_INTERNE, SUPER_ADMIN
- Auto-log de l'export lui-même dans audit (méta-traçabilité)

S16.C — Notifications transparency (pattern CDI Event Observer)
- AuditOperationLoggedEvent record + helper estSensible() (DELETE / PAYMENT_* / BUDGET_APPROVED / AID_REQUEST_APPROVED / EXPORT / VALIDATE / SoD-violation)
- AuditTrailService.log() fire le CDI event après persist
- AuditNotificationService observe @Observes(AFTER_SUCCESS) — notifie via NotificationService existant (DRY, pas de nouveau client mail)
- Sujets/corps localisés français + priorité automatique (HAUTE pour DELETE/PAYMENT_FAILED/SoD, NORMALE pour confirmations, BASSE pour exports)
- Fail-soft : exception notification ne bloque jamais l'audit principal

Tests (10 nouveaux S16.C, 21/21 cumulé audit)
- onAuditOperation × 5 (sensible/non-sensible/SoD/null/userId-null)
- mapping helpers × 4 (sujet × 8 actions, sodPriority, priorité × 6 cas, corps × 2)
2026-04-25 16:28:51 +00:00
dahoud
e4d7c8e4b7 feat(sprint-15 backend 2026-04-25): Live Activity Feed — endpoint /api/audit-trail/recent + tests
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m50s
Transparency opérationnelle UnionFlow — opérations sensibles consultables en temps réel selon scope.

Repository
- findRecent(limit) : N opérations les plus récentes, toutes orgs
- findRecentByOrganisation(orgId, limit) : pour scope ORG
- findRecentByUser(userId, limit) : pour scope SELF
- Tous clamps limit à [1, 500] (sécurité DoS)

Service AuditTrailQueryService
- listerRecentes(scope, orgId, userId, limit) : dispatcher SELF/ORG/ALL avec fallback liste vide si UUID requis manquant ; insensible à la casse

Resource REST AuditTrailOperationResource
- GET /api/audit-trail/recent?scope=SELF&orgId=...&userId=...&limit=50
- Default scope=SELF, limit=50
- @RolesAllowed étendu (MEMBRE inclus pour scope SELF) — un membre peut voir SES propres opérations

Tests (7 nouveaux, 11/11 cumulé service)
- recentes_All / Null defaults to ALL / Org / OrgWithoutId / Self / SelfWithoutUser / CaseInsensitive
2026-04-25 16:08:33 +00:00
dahoud
7c3352ed48 feat(sprint-13.A backend 2026-04-25): OrganisationService.convertToResponse propage referentielComptable + complianceOfficerId
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m21s
Suite à enrichissement OrganisationResponse api 1.0.9. Mapping Entity → Response
maintenant complet pour le front-end (Sprint 10 avait déjà le mapping
Request → Entity, manquait Entity → Response).

Bump dépendance api 1.0.8 → 1.0.9. Quarkus inchangé (3.27.3).

ACTION USER : `mvn install` côté unionflow-server-impl-quarkus pour valider.
2026-04-25 15:22:50 +00:00
dahoud
f267eeebfc fix(sprint-10 backend): @Builder n'expose pas actif() (parent BaseEntity), setter explicite
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m27s
BaseEntity contient actif (Boolean), mais BeneficiaireEffectif et RoleDelegation utilisent
@Builder simple (pas @SuperBuilder) → builder ne propage pas les champs parent.

Solution : .build() puis setActif(true). Pas de @SuperBuilder ici (changement de signature
diffuse, hors-scope Sprint 10).

Tests Sprint 10 backend désormais 12/12 verts (BeneficiaireEffectifService 8 + AuditTrailQueryService 4).
2026-04-25 12:46:22 +00:00
dahoud
241533efa6 feat(sprint-10 backend 2026-04-25): Resources REST UBO + audit trail + délégation + enrich update org
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m30s
Expose les features Sprints 1-2 via API REST. Architecture stricte respectée :
Resource ↔ Service ↔ Repository ↔ Entity ↔ DTO. Mapping centralisé en Service.

Bump dépendance api 1.0.7 → 1.0.8 (DTOs nouveaux)

UBO (Instr. BCEAO 003-03-2025)
- BeneficiaireEffectifService : creer (validation cible obligatoire), mettreAJour (PATCH), desactiver (soft-delete), validation seuilPourcentage (somme cumul ≤ 100, exclusion en mode update), audit trail systématique
- BeneficiaireEffectifResource : CRUD /api/kyc/beneficiaires-effectifs, filtres queryParam (kycDossierId | organisationCibleId | pep), @RolesAllowed COMPLIANCE_OFFICER + ADMIN_ORG + SUPER_ADMIN

Audit trail (CQRS read-side)
- AuditTrailQueryService NEW : 5 méthodes lecture seule (parUtilisateur, historiqueEntite, parOrganisation, violationsSod, operationsFinancieres) + mapping Entity→DTO
- AuditTrailOperationResource : /api/audit-trail/{by-user|by-entity|by-organisation|sod-violations|financial}, parsing dates ISO + fallbacks
- Distinct du AuditTrailService (write-side dans security/) : Single Responsibility appliqué

Délégation rôles (Sprint 2 service réutilisé)
- RoleDelegationService enrichi : creerDepuisRequest (DTO→entité→creer existant), revoquerEtRetourner, listerParOrganisation, toResponse (mapping centralisé)
- RoleDelegationRepository : findByOrganisation
- RoleDelegationResource : POST/DELETE/GET /api/role-delegations

Enrichissement Organisation update (DRY)
- OrganisationService.convertFromUpdateRequest : parseReferentielComptable (fallback ReferentielComptable.defaultFor) + complianceOfficerId
- OrganisationService.mettreAJourOrganisation : propagation conditionnelle des nouveaux champs

Tests (en attente publication api 1.0.8 — install local nécessaire)
- BeneficiaireEffectifServiceTest : 8 tests verifierSeuilPourcentage (OK / limite / dépassement / excludeId / null / inactifs ignorés) + creer + toResponse mapping
- AuditTrailQueryServiceTest : 4 tests parUtilisateur, sodViolations, toResponse mapping, historiqueEntite

ACTION USER : `mvn install` côté unionflow-server-api pour rendre 1.0.8 dispo en m2 local + publier via script/publish-api.sh pour Gitea.
2026-04-25 12:32:41 +00:00
dahoud
4d400dc48d feat(sprint-7 P1-NEW-15 2026-04-25): PI-SPI Readiness check (8 vérifications) + endpoint admin
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m46s
Service ops/compliance pour valider l'état d'intégration PI-SPI BCEAO avant activation production.

PispiReadinessService — 8 vérifications structurées
- OAUTH2_CREDENTIALS (BLOCKING) : client_id + client_secret
- API_KEY (BLOCKING) : header X-API-Key obligatoire BCEAO
- MTLS_KEYSTORE (BLOCKING) : path + password + fichier .p12 existant
- MTLS_TRUSTSTORE (WARNING) : configuré + fichier existant (fallback cacerts si absent)
- WEBHOOK_SECRET (BLOCKING) : HMAC-SHA256 webhooks
- BASE_URL (WARNING) : sandbox vs production détecté automatiquement
- TAUX_EUR_XOF (WARNING) : taux récent ≤ 7 jours (sinon obsolète)
- PROVIDER_CONFIGURED (BLOCKING) : PispiAuth.isConfigured() = true (synthèse)

Statut global agrégé
- READY — tous PASS
- DEGRADED — uniquement WARNING en échec (sandbox OK, prod à risque)
- BLOCKED — au moins un BLOCKING en échec (sandbox impossible)

Endpoint /api/admin/pispi/readiness
- @RolesAllowed SUPER_ADMIN, COMPLIANCE_OFFICER
- HTTP 200 si READY/DEGRADED, 503 si BLOCKED
- Réponse JSON : globalStatus, baseUrl, checks détaillés, blockingIssues, warnings

Helpers publics ajoutés (pour readiness sans casser l'encapsulation)
- PispiAuth : hasClientId(), hasClientSecret(), hasApiKey(), keystorePath(), keystorePassword(), truststorePath(), truststorePassword()
- PispiSignatureVerifier : hasWebhookSecret()

Tests (15/15 verts)
- BLOCKED tout vide, READY tout configuré, DEGRADED warnings only
- Checks individuels OAuth2/ApiKey/Keystore (path absent / fichier inexistant / OK), Truststore warning, Webhook, BaseUrl sandbox/prod, Taux récent/obsolète, Provider
2026-04-25 10:48:59 +00:00
dahoud
86842f27af feat(sprint-6 P2-NEW-7 2026-04-25): multi-devise + KYC non-résident diaspora + tests
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m11s
Ouvre UnionFlow à la diaspora UEMOA (France, USA, Canada, UK, Suisse...).

Entités & migration
- Enum Devise (10 valeurs : XOF, XAF, EUR, USD, GBP, CAD, CHF, GHS, NGN, MAD)
  - Zones : UEMOA, CEMAC, CEDEAO, EUROPE, AMERIQUE, MAGHREB
  - DEVISES_INTERNATIONALES : EUR/USD/GBP/CAD/CHF (déclenchent AML international)
- Entité TauxChange (devise_source × devise_cible × date_validite, taux NUMERIC(18,8))
- Repository : trouverExact, trouverPlusRecent (≤ date)
- V49 :
  - Table taux_change (contrainte unicité paire+date, devises distinctes)
  - Seed BCEAO_FIXED EUR↔XOF + taux indicatifs USD/GBP/CAD au 2026-04-25
  - Membres : pays_residence (ISO-3), numero_passeport, numero_fiscal_etranger, est_diaspora, devise_preferee
  - KycDossiers : pays_origine_fonds, justificatif_residence_etrangere, niveau_due_diligence (SIMPLIFIE/STANDARD/RENFORCE)

DeviseConversionService
- Stratégie de résolution : direct → inverse → pivot via XOF → fallback récent ≤ date
- Cache thread-safe (ConcurrentHashMap, TTL 1h)
- TauxIntrouvableException si aucun taux résolvable
- invaliderCache() pour reload après import batch

KycDiasporaService
- validerCoherence : passeport obligatoire si diaspora, pays_residence ≠ UEMOA, format passeport regex
- determinerNiveauDueDiligence (Instr. BCEAO 001-03-2025) :
  - PEP → RENFORCE
  - Diaspora pays sécurisés (UE/G7/Asie) → STANDARD
  - Diaspora FATF grey-list → RENFORCE
  - Diaspora pays inconnu → RENFORCE par prudence
- depasseSeuilAmlInternational : seuil 1000 EUR équivalent, false sur devises locales
- PAYS_UEMOA hardcodé (8 pays), PAYS_GREY_LIST_FATF snapshot 2026-04-25

Tests Sprint 6 (34/34 verts)
- DeviseTest : 5 tests (référence, internationales, zones, libellés)
- DeviseConversionServiceTest : 10 tests (identité, direct, inverse, pivot XOF, fallback récent, cache, invalider, exception, inputs invalides)
- KycDiasporaServiceTest : 19 tests (cohérence valide/sans passeport/pays UEMOA/pays étranger, due diligence PEP/FRA/grey-list/inconnu/UEMOA, seuil EUR/USD avec taux/sans taux/XOF/null)
2026-04-25 10:33:05 +00:00
dahoud
a0b2690c17 feat(sprint-5 P2-NEW-3 2026-04-25): reporting trimestriel ControleurInterne automatisé + scheduler + tests
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m26s
Rapport trimestriel agrégé pour le Contrôleur Interne (source AG + inspections BCEAO/ARTCI).

Entités & migration
- RapportTrimestrielControleurInterne (BaseEntity + JSONB contenu + bytea PDF + hash SHA-256)
- V48 : table rapports_trimestriels_controleur_interne, contraintes, indexes
- Repository : trouverParOrgAnneeTrimestre, listerParOrgAnnee, listerNonSignes

Service RapportTrimestrielService
- genererRapport(orgId, annee, trimestre) : agrège ComplianceSnapshot + DOS CENTIF + formations LBC/FT + anomalies SoD audit trail + demandes aide
- construireJson : structure conformite/activite/alertes
- genererPdf : OpenPDF A4 avec sections 1.Conformité 2.Activité 3.Alertes + bloc signature
- signer(rapportId, signataireId) : calcule SHA-256 du JSON, fige le statut
- archiver(rapportId) : passe SIGNE → ARCHIVE
- Idempotent en DRAFT (régénération possible) ; immuable en SIGNE/ARCHIVE

Resource RapportTrimestrielResource
- GET /api/rapports/trimestriel?orgId&annee — lister
- POST /api/rapports/trimestriel/generer — CONTROLEUR_INTERNE / SUPER_ADMIN
- POST /api/rapports/trimestriel/{id}/signer — CONTROLEUR_INTERNE
- POST /api/rapports/trimestriel/{id}/archiver — CONTROLEUR_INTERNE / PRESIDENT
- GET /api/rapports/trimestriel/{id}/pdf — application/pdf

Scheduler RapportTrimestrielScheduler
- @Scheduled cron 0 17 2 1 1,4,7,10 ? — 1er jan/avr/jul/oct à 02:17
- Génère pour toutes les orgs actives le trimestre précédent
- Override possible via unionflow.reporting.trimestriel.cron
- ConcurrentExecution.SKIP

RoleConstant
- Ajout CONTROLEUR_INTERNE, COMPLIANCE_OFFICER, COMMISSAIRE_COMPTES (utilisés depuis V45)

Tests Sprint 5 (20/20 verts)
- RapportTrimestrielServiceTest : 15 tests (debutTrimestre, finTrimestre, hash SHA-256, JSON alertes, PDF non vide)
- RapportTrimestrielSchedulerTest : 5 tests (trimestrePrecedent — incluant rollover année)
2026-04-25 10:13:07 +00:00
dahoud
b0ee8881fb feat(sprint-4 P1-NEW-8/9 2026-04-25): docker-compose Keycloak 26.6.1 + fix Mockito strict-stubbing test KC
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m25s
P1-NEW-8/9 — Préparation migration Keycloak 23 → 26.6.1 + Organizations GA
- docker-compose.kc26.yml : compose alternatif KC 26.6.1 avec --features=organization
- Bind-mount realm import depuis src/main/resources/keycloak/realms
- Healthcheck readiness probe + KC_HEALTH_ENABLED
- Postgres 15 dédié, volume persistant
- Réf : ARCH_KEYCLOAK_26.md
- Permet validation locale avant cutover (compose dev intact)

Fix tests KeycloakAdminHttpClientTest (4 erreurs Mockito UnnecessaryStubbing)
- Helper mockResponse : lenient() sur body() (lu uniquement sur paths erreur/JSON parsing)
- 9/9 tests passent désormais

État Sprint 4 (déjà livré dans sessions antérieures, validé ici) :
- Entité Organisation.keycloakOrgId + migration V37
- Service MigrerOrganisationsVersKeycloakService (idempotent, 9 tests)
- OrganisationContextResolver (parsing claim 'organization' JWT, 12 tests)
- AdminKeycloakOrganisationResource (endpoint admin migration)
- KeycloakAdminHttpClient (sessions, 9 tests)

Tests Sprint 4 : 36/36 passent (resolver 12 + migration 9 + admin HTTP 9 + context holder 6)

Reste pour migration finale (post-Sprint 4) :
- Validation manuelle docker compose -f docker-compose.kc26.yml up -d
- Bascule production : remplacer compose KC23 par KC26
- Refactoring backend : suppression OrganisationContextFilter + headers custom
2026-04-25 08:58:00 +00:00
dahoud
8b589477ec feat(sprint-3 P1+P2 2026-04-25): compliance dashboard + PEP screening + formations LBC/FT + goAML XML + tests
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m15s
P1-NEW-11 — Tableau de bord conformité
- ComplianceDashboardService : score 0-100 avec 9 indicateurs pondérés (compliance officer, AG annuelle, rapport AIRMS, dirigeants CMU, taux KYC, taux formation LBC/FT, CAC, FOMUS-CI, couverture UBO)
- ComplianceDashboardResource : GET /api/compliance/dashboard

P1-NEW-11 — PEP screening externe
- PepScreeningProvider (interface) + records PepScreeningResult / PepMatch
- InMemoryPepScreeningProvider : fallback dev avec similarité Levenshtein normalisée (seuil 0.80)
- PepScreeningService : cache LRU 5000 entrées, TTL 24h
- Pluggable via @Alternative @Priority pour Youverify / ComplyAdvantage en prod

P1-NEW-12 — Module formation LBC/FT obligatoire annuelle
- FormationLbcFt + ParticipationFormationLbcFt (entités)
- FormationLbcFtService : creer, inscrire, marquerPresent, certifier (score >= 70), estCertifieAnneeCourante
- Repositories : trouverCertificationAnnee, findATenir
- V47 migration : formations_lbcft, participations_formation_lbcft, pep_screening_cache

P2-NEW-4 — goAML XML (anticipation adoption CI)
- GoAmlXmlService : génération XML standard ONUDC (report, transaction, t_person, t_account)
- Reporting person anonymisé ([REDACTED], rôle Compliance Officer)
- POST /api/aml/dos/goaml @RolesAllowed(COMPLIANCE_OFFICER, SUPER_ADMIN)

Tests Sprint 3 (15 tests, 100%) :
- FormationLbcFtTest : 2 tests (builder, override type)
- GoAmlXmlServiceTest : 4 tests (XML non vide, champs clés, anonymisation, country code CIV)
- InMemoryPepScreeningProviderTest : 9 tests (match, nationalité, vide, similarité Levenshtein)
2026-04-25 08:37:06 +00:00
c54092bd78 feat(sprint-2 P0+P1 2026-04-25): DOS CENTIF + Reporting AIRMS + PV OHADA + workflow demande aide v2 + délégation rôles + SYCEBNL donateurs + tests
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m10s
P0-NEW-16 — DOS CENTIF (Lignes directrices CENTIF mars 2025)
  - DosCentifService.genererDosWord() : XWPFDocument structurée 6 sections
  - DosCentifService.genererReleveExcel() : XSSFWorkbook avec opérations atypiques
  - DosCentifResource @RolesAllowed COMPLIANCE_OFFICER : POST /api/aml/dos/{word,excel}
  - Confidentialité absolue (jamais persisté disque, audit trail EXPORT)

P1-NEW-1 — Reporting AIRMS triple
  - RapportAirmsService.genererRapportTriple() : OpenPDF, 3 sections + cover
  - DTOs records : RapportTechnique (effectifs, sinistralité, délais),
    RapportMoral (vie associative, formations, activités),
    RapportFinancier (P&L, ratios prudentiels, trésorerie, fonds dédiés SYCEBNL)
  - Endpoint POST /api/airms/rapports/triple

P1-NEW-2 — Module PV OHADA (AG/CA)
  - V46 : table proces_verbaux (quorum, OJ JSONB, résolutions JSONB, hash SHA-256, signatures)
  - Entité ProcesVerbal + repo ProcesVerbalRepository
  - ProcesVerbalService :
    * quorumRequisDefaut() : 50% AG ord / 66.67% AG extra/CA
    * calculerEtFixerQuorum() : (présents+représentés)/convoqués × 100
    * adopter() : valide quorum, fige hash SHA-256
    * signer() : vérif hash inchangé (immuabilité), signature électronique
    * archiver() : statut ARCHIVE pour conservation OHADA 10 ans

P1-NEW-3 — Workflow demande d'aide v2
  - V46 : extension demandes_aide (etape, animateur_zone, gps_enquete, avis_comite, decision_ca)
  - V46 : extension types_aide (plafond_annuel_membre, plafond_enveloppe_annuelle, justificatifs_requis)
  - DemandeAide enrichie : 5 étapes DEPOSE → ENQUETE → AVIS_COMITE → DECISION_CA → PAYE → CLOTURE
  - DemandeAideV2Service :
    * Transitions typées avec checks d'état
    * SoD : approbateur CA ≠ animateur enquête
    * Audit trail enrichi à chaque transition

P1-NEW-5 — Délégation temporaire rôles
  - V46 : table role_delegations (delegant, delegataire, role, dates, statut, motif)
  - Entité RoleDelegation + isActiveAt(instant)
  - RoleDelegationService :
    * creer() : vérif SoD avant création (pas de conflit avec rôles existants délégataire)
    * revoquer() : statut REVOQUEE
    * rolesEffectifs() : directs ∪ délégués actifs
    * marquerExpirees() : scheduler quotidien

P1-NEW-13 — Registre donateurs SYCEBNL
  - V46 : tables donateurs + dons_recus (numéraire/nature/bénévolat/legs)
  - Affectation : LIBRE / FONDS_DEDIE / PROJET_SPECIFIQUE
  - Reçu fiscal (numero_recu, date_emission_recu)
  - Entités Donateur + DonRecu + repos
  - DonRecuRepository.totalEntre() pour reporting AIRMS/SYCEBNL

P1-NEW-14 — Membres honoraires/bienfaiteurs
  - V46 : ALTER membres_organisations.qualite_speciale (HONORAIRE/BIENFAITEUR/FONDATEUR)

Tests Sprint 2 (13 nouveaux, 0 failure) :
  - ProcesVerbalServiceTest (8) : quorum défaut, atteint/non-atteint, hash format/immuabilité/diff
  - RoleDelegationTest (5) : isActiveAt selon période et statut
2026-04-25 01:53:16 +00:00
7099f554fe feat(p0-2026-04-25): mobile SPKI pinning + Play Integrity/App Attest + tests Sprint 1
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m7s
P0-NEW-21 — SPKI Pinning + rotation Firebase Remote Config (mobile)
  - lib/core/security/spki_pinning_service.dart : digest SHA-256 SPKI/cert
  - Liste de pins active depuis Firebase Remote Config (key 'spki_pins')
  - Fallback statique au bundle si Firebase indisponible
  - Multi-pin (leaf + backup + intermediate) pour transitions sans downtime
  - Hosts pinnés : api.lions.dev, security.lions.dev
  - Câblé dans ApiClient._configureSslPinning() (remplace check CN obsolète)

P0-NEW-22 — Play Integrity (Android) + App Attest (iOS) (mobile)
  - lib/core/security/app_device_integrity_service.dart
  - Token attestation court (cache 60s) avec challenge backend
  - Bypass automatique en kDebugMode
  - À compléter avec un Dio interceptor X-Device-Integrity-Token avant go-live

pubspec.yaml :
  - freerasp 7.0.0 → 7.5.1
  - +app_device_integrity 1.1.0
  - +firebase_core 3.6.0 + firebase_remote_config 5.1.3

Tests Sprint 1 (40 tests, 0 failure) :
  - ReferentielComptableTest (6 cas) : defaultFor mapping
  - AmlSeuilsTest (10 cas) : seuils 10M/5M/1M, pays UEMOA, depasseSeuil
  - SoDPermissionCheckerTest (13 cas) : validation distincte, combinations interdites,
    compliance officer eligibility
  - PispiRtpRequestTest (6 cas) : validation contraintes
  - PispiRtpResponseTest (5 cas) : helpers status
2026-04-25 01:24:53 +00:00
144137656f feat(p0-2026-04-25): PI-SPI auth 3-facteurs + RTP + alias
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m32s
P0-NEW-2 — Authentification PI-SPI 3-facteurs (spec sandbox developer.pispi.bceao.int)
  - PispiAuth : OAuth2 + mTLS (PKCS12 keystore + truststore optionnel) + X-API-Key
  - SSLContext TLS 1.3 + KeyManagerFactory + TrustManagerFactory
  - HttpClient mTLS lazy + cache, HTTP/2, timeout 15s/30s
  - isConfigured() pour bascule auto mode mock si secrets absents

P0-NEW-3 — Request To Pay (RTP — pain.013/014)
  - dto/PispiRtpRequest (record validate())
  - dto/PispiRtpResponse avec helpers isAccepted()/isRefused()/...
  - PispiClient.initiateRtp() + getRtpStatus()
  - Cas d'usage : appel cotisation initié par la SFD vers le membre

P0-NEW-4 — Gestion d'alias (téléphone/email → compte SFD)
  - dto/PispiAlias (record + Types : PHONE_NUMBER/EMAIL/NATIONAL_ID/CUSTOM)
  - PispiClient.resolveAlias() + createAlias() + revokeAlias()
  - Cas d'usage : '+22507XXX@unionflow' ou 'cotisation-{slug}@unionflow'

PispiClient harmonisé : baseRequestBuilder() central avec 3 headers obligatoires, gestion 404 sur resolveAlias, timeouts 30s.
2026-04-25 01:18:46 +00:00
d8006c8425 feat(p0-2026-04-25): multi-référentiel comptable + UBO + audit trail + SoD + seuils AML
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m11s
Sprint 1 P0 (consolidation 2026-04-25, ETAT_PROJET_METIER_2026-04-25.md) :

P0-NEW-9/10/11 — Multi-référentiel comptable
  - enum ReferentielComptable (SYSCOHADA / SYCEBNL / PCSFD_UMOA)
  - Organisation.referentielComptable + mapping defaultFor(typeOrganisation)
  - V43 : colonne + check + index + mapping initial des orgs existantes

P0-NEW-13 — Bénéficiaires effectifs (UBO) — Instruction BCEAO 003-03-2025
  - Entité BeneficiaireEffectif + repository
  - V44 : table beneficiaires_effectifs (FK kyc_dossier, UBO + PEP + sanctions)
  - Conservation 10 ans (directive 02/2015/CM/UEMOA)

P0-NEW-14 — Compliance Officer (Instruction BCEAO 001-03-2025)
  - Organisation.complianceOfficerId + V43 colonne + index

P0-NEW-15 — Seuils AML alignés (Instruction BCEAO 002-03-2025)
  - AmlSeuils : 10M FCFA intra-UEMOA / 5M FCFA entrée-sortie / 1M FCFA espèce
  - Liste pays UEMOA ISO 3166-1
  - Méthodes seuilApplicable() / depasseSeuil() / depasseSeuilEspece()

P0-NEW-17/18 — Rôles PRESIDENT + CONTROLEUR_INTERNE + suppléants
  - V45 seed : PRESIDENT, VICE_PRESIDENT, CONTROLEUR_INTERNE, ANIMATEUR_ZONE, SECRETAIRE_ADJOINT, TRESORIER_ADJOINT
  - Catégories GOUVERNANCE / CONTROLE / OPERATIONNEL

P0-NEW-19 — Audit trail enrichi (SYSCOHADA + AUDSCGIE)
  - V45 : table audit_trail_operations (acteur, action, contexte multi-org, payload JSONB, SoD)
  - Entité AuditTrailOperation + AuditTrailOperationRepository
  - AuditTrailService (log avec contexte automatique depuis OrganisationContextHolder)
  - OrganisationContextHolder enrichi (roleActif, currentUserId, currentUserEmail)

P0-NEW-20 — SoD (Separation of Duties) — SYSCOHADA + AUDSCGIE + BCEAO Circulaire 03-2017
  - SoDPermissionChecker.checkValidationDistinct() (4-eyes principle)
  - .checkRoleCombination() (combinaisons interdites : Trésorier+Président, etc.)
  - .checkComplianceOfficerEligibility() (Instruction BCEAO 001-03-2025)
  - SoDCheckResult record avec audit trail automatique

P0-NEW-24 — Champ numero_cmu sur Membre (Loi 2014-131 CI)
  - Membre.numeroCMU + V43 colonne + check format 11 caractères + index
  - Auto-déclaration (pas d'API publique CNAM disponible)

BUILD SUCCESS.
2026-04-25 01:15:25 +00:00
6e9841b3bb fix(disaster-recovery 2/2): restaurer 242 fichiers Java modifiés par a72ab54
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m22s
Suite à la récupération précédente (044ca4b) qui n'avait restauré que les
fichiers SUPPRIMÉS, ce commit restaure les MODIFICATIONS d'entités/services
qui étaient nécessaires pour que les fichiers restaurés compilent.

Restaurés depuis a72ab54^ (= 31330d9 + corrections) :
- Entities : Organisation, FormuleAbonnement, AuditService, MembreOrganisation, SouscriptionOrganisation, etc.
- Services : MigrerOrganisationsVersKeycloakService, ComptabilitePdfService, KycAmlService, AuditService.logKycRisqueEleve, etc.
- Resources : PaiementUnifieResource, etc.

Backend compile désormais (BUILD SUCCESS).
2026-04-25 01:05:08 +00:00
044ca4bd7e fix(disaster-recovery): restaurer 134 fichiers accidentellement supprimés par a72ab54
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 3m46s
Le commit a72ab54 (chore docker Dockerfile racine) a involontairement balayé
des fichiers du commit 31330d9 (PI-SPI, KYC, RLS, mutuelle parts, comptabilité
PDF) lors d'un git add -A trop large.

Restauration de l'intégralité des fichiers depuis a72ab54^ :
- 11 migrations Flyway V32-V42 (parts sociales, SYSCOHADA, Keycloak Org Id, KYC, RLS, Provider défaut, FCM, App DB Roles)
- Package payment/pispi/ complet (PispiAuth, PispiClient, PispiIso20022Mapper, PispiSignatureVerifier, PispiWebhookResource, dto/Pacs008Request, dto/Pacs002Response, PispiPaymentProvider)
- Package payment/{wave,orangemoney,mtnmomo}/* (PaymentProvider impls)
- Package payment/orchestration/ (PaymentOrchestrator, PaymentProviderRegistry)
- Entités KycDossier, mutuelle/parts/* (ComptePartsSociales, TransactionPartsSociales)
- Mappers, repositories, resources associés
- Services KycAmlService, ComptabilitePdfService, ReleveComptePdfService, InteretsEpargneService
- AdminKeycloakOrganisationResource, KycResource, PaiementUnifieResource
- Tests unitaires PI-SPI, KYC, mutuelle parts
2026-04-25 01:00:03 +00:00
b434282000 docs: Quarkus 3.15.1→3.27.3 LTS, Java 17→21, lionsctl -j 21, Dockerfile racine, pré-requis infra
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m9s
2026-04-24 18:05:43 +00:00
a72ab54abd chore(docker): add root Dockerfile pinning ubi8/openjdk-21:1.21 + UID 1001 for lionsctl pipeline
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m2s
2026-04-24 16:19:25 +00:00
fb3a32817b chore(quarkus-327): bump to Quarkus 3.27.3 LTS, make pom autonomous, fix 3 tests (NPE guard, equalsHashCode with shared refs), rename deprecated config keys 2026-04-23 14:45:54 +00:00
dahoud
8cec38f7b3 fix(monitoring): corriger calcul CPU — getProcessCpuLoad au lieu de loadAverage/processors
Le calcul précédent `getSystemLoadAverage() / getAvailableProcessors() * 100`
utilisait :
- getSystemLoadAverage() : charge 1min du NODE Linux hôte entier (12 CPU sur prod VPS)
- getAvailableProcessors() : limite conteneur K8s (1 CPU pour le pod UnionFlow)

Résultat : load 1.5 sur le node → cpuUsage = (1.5 / 1) * 100 = 150% capé à 100%.
Déclenchement constant d'alertes "CPU 100%" (19 faux positifs / 24h sur prod
le 20-21/04/2026) dès que le node fait autre chose que dormir.

Correctif : utilise com.sun.management.OperatingSystemMXBean.getProcessCpuLoad()
qui retourne la charge CPU du process JVM courant (0.0-1.0), conscient du
conteneur. Branche -1 préservée (API non dispo sur certaines JVM).

Tests mis à jour : AlertMonitoringServiceMockStaticCoverageTest injecte
désormais un com.sun.management.OperatingSystemMXBean et mocke
getProcessCpuLoad() (compatible mock-maker-inline déjà configuré).
AlertMonitoringServiceTest conserve sa logique OS-agnostique via des
thresholds extrêmes (-1 toujours / 100 jamais).
2026-04-21 13:38:31 +00:00
dahoud
31330d95e9 feat: accumulated work — PI-SPI, KYC, RLS, mutuelle parts, comptabilité PDF + startup fixes
## PI-SPI BCEAO (P0.3 — deadline 30/06/2026)
- package payment/pispi/ complet : PispiAuth (OAuth2), PispiClient (HTTP brut),
  PispiIso20022Mapper (pacs.008/002), PispiSignatureVerifier (HMAC-SHA256),
  PispiWebhookResource (/api/pispi/webhook), DTOs ISO 20022
- PaymentOrchestrator + PaymentProviderRegistry pour l'orchestration multi-provider
- Mode mock automatique si credentials absents (dev)

## KYC AML
- entity/KycDossier, KycResource, KycAmlService + tests
- Migration V38 (create_kyc_dossier_table)

## RLS (PostgreSQL Row-Level Security) — isolation multi-tenant
- RlsConnectionInitializer, RlsContextInterceptor, @RlsEnabled annotation
- Migration V39 (PostgreSQL RLS Tenant Isolation) + V42 (app DB roles)
- Tests unitaires RlsConnectionInitializerTest, RlsContextInterceptorTest
- Tests d'intégration RlsCrossTenantIsolationTest (@QuarkusTest + IntegrationTestProfile)

## Mutuelle — Parts sociales
- entity/mutuelle/parts/ComptePartsSociales, TransactionPartsSociales
- Service, resource, mapper, repository + tests
- InteretsEpargneService + ReleveComptePdfService

## Comptabilité PDF
- ComptabilitePdfService (OpenPDF), ComptabilitePdfResource
- Tests ComptabilitePdfServiceTest, ComptabilitePdfResourceTest

## Migrations Flyway (SYSCOHADA + Keycloak Orgs)
- V36 SYSCOHADA Plan Comptable Complet : seeds comptes standards UEMOA,
  trigger init_plan_comptable_organisation, alignement schéma V1 → entités
- V37 keycloak_org_id sur organisations (P0.2 migration KC 26)
- V40 provider_defaut sur FormuleAbonnement
- V41 fcm_token sur utilisateurs (FCM notifications push)

## Fixes startup (SmallRye Config 3.20 + schéma)
- 8× @ConfigProperty(defaultValue = "") → Optional<String>
  (firebase, pispi.*, mtnmomo, orange) — empty default rejetés par SmallRye 3.20
- application.properties : mappings secrets env var sous %prod. uniquement
- V36 : drop colonne obsolète 'numero' de V1 quand Hibernate a créé 'numero_compte'
- V36 : remplacement UNIQUE global sur journaux_comptables.code par composite
  (organisation_id, code) pour autoriser plusieurs orgs avec code 'ACH'/'VTE'/etc
- V39 : escape placeholder ${VAR} → <VAR> dans lignes commentées
  (Flyway parser évalue les placeholders même dans les commentaires)
- V41 : table 'membres' → 'utilisateurs' (nom correct selon entité Membre)
- JournalComptable entity : @UniqueConstraint composite au lieu de unique=true
- MembreResource : example @Schema JSON valide (['...'] → [])
- IntegrationTestProfile : auto-détection Docker via `docker info`, fallback
  vers PostgreSQL local sans DevServices

## Dev config
- application-dev.properties : quarkus.devservices.enabled=false +
  quarkus.kafka.devservices.enabled=false (pas besoin de Docker pour dev)
- quarkus.flyway.placeholder-replacement=false
- Secrets dev (wave.*, firebase, pispi) en mode mock automatique

## Phase 8 tests (complète)
- 170 fichiers modifiés/ajoutés, 23425+ insertions
- Tests RBAC (@QuarkusTest) pour MembreResource lifecycle
- Tests OrganisationContextFilter multi-org
- Tests SouscriptionQuotaOptionC, KycAmlService, EmailTemplate, etc.

Résultat : Backend démarre en 64s sur port 8085 avec 36 features installées.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:40:55 +00:00
dahoud
9a53ce4077 feat: sécuriser endpoints organisations + stats par org + fix IP dev
- PUT /{id}: check appartenance ADMIN_ORGANISATION (403 si pas membre)
- GET /statistiques: stats scoped à l'org active pour ADMIN_ORGANISATION
- OrganisationService.obtenirStatistiquesParOrganisation(): stats mono-org
- MembreOrganisationRepository.findByMembreEmailAndOrganisationId()
- application-dev: IP 192.168.1.145→localhost pour Keycloak
2026-04-18 08:07:04 +00:00
dahoud
9f14c2e345 refactor: supprimer setTypeAssociation/setTypeLibelle doublons dans OrganisationService
- OrganisationService.convertToResponse: ne plus setter typeAssociation ni typeLibelle
- Utiliser uniquement typeOrganisation et typeOrganisationLibelle
- Corriger tests: assertions sur typeOrganisationLibelle au lieu de typeLibelle
2026-04-17 20:00:34 +00:00
dahoud
4b2b326afe refactor: nettoyer terminologie entité→organisation et corriger mapping TONTINE
- ADMIN_ENTITE→ADMIN_ORGANISATION dans Javadoc et README
- OrganisationModuleService: retirer TONTINE de MUTUELLE (BCEAO-réglementé, incompatible)
- Ajouter TONTINE aux ASSOCIATION et CLUB_SERVICE (pratique courante Afrique de l'Ouest)
- V18 migration: aligner modules_requis avec le code Java
2026-04-17 19:19:48 +00:00
dahoud
194a1e7017 fix(prod): ajouter flyway.repair-at-start pour corriger checksum V18 modifié
La V18 a été modifiée (fusion MUTUELLE_EPARGNE+CREDIT → MUTUELLE).
En prod, le checksum en DB ne correspond plus → Flyway refuse de démarrer.
repair-at-start met à jour la schema_history automatiquement.
2026-04-17 00:23:51 +00:00
dahoud
a4e5b6af12 fix(souscription): réécrire activerAdminOrganisation — promouvoir le payeur, pas un membre aléatoire
Problème : après paiement Wave, le membre restait SIMPLEMEMBER car :
1. La méthode bouclait sur TOUS les liens de l'org et promouvait le
   premier non-ACTIF (pas forcément le payeur)
2. Si aucun lien n'existait, créait un lien avec SIMPLEMEMBER sans promotion
3. Early return après la première promotion → si le mauvais membre était
   promu, le payeur restait bloqué

Nouvelle logique :
1. Identifier le caller (JWT email) = le membre qui a réellement payé
2. Vérifier/créer son lien MembreOrganisation (activer si en attente)
3. Promouvoir ce membre spécifique en ORGADMIN (DB)
4. Syncer Keycloak ADMIN_ORGANISATION (non-bloquant)

Résultat : après paiement, le payeur est automatiquement promu ORGADMIN
avec statut ACTIF et accède directement à son dashboard.
2026-04-16 14:24:17 +00:00
dahoud
4a1ca88517 test: corriger constructeurs OrganisationSummaryResponse 10→12 args (ville+pays)
3 fichiers de test utilisaient l'ancien constructeur à 10 arguments.
Ajout de null, null pour ville et pays dans tous les appels.
2026-04-16 14:07:28 +00:00
dahoud
51bb996eef fix(org): passer ville + pays au constructeur OrganisationSummaryResponse
Ajout des 2 champs manquants dans convertToSummaryResponse() pour que
la liste des organisations affiche la localisation.
2026-04-16 12:29:37 +00:00
dahoud
48604bbbc6 feat(types-ref): auto-génération du code technique depuis le libellé
TypeReferenceService.creer() :
- Si code non fourni ou vide : auto-généré depuis le libellé via genererCodeDepuisLibelle()
- Si code fourni : nettoyé via normaliserCode() (strip accents, UPPER_SNAKE_CASE)
- Dédoublonnage automatique : si le code existe, suffixe _2, _3, etc.

Méthodes ajoutées :
- genererCodeDepuisLibelle(String) : libellé → UPPER_SNAKE_CASE sans accents
  Ex: 'Mutuelle d''Épargne' → 'MUTUELLE_D_EPARGNE'
- normaliserCode(String) : Normalizer.NFD + strip diacritics + [^A-Za-z0-9] → _
- assurerUniciteCode(String, String, UUID) : suffixe incrémental si doublon

Les types système (est_systeme=true, seeded en V18) gardent leurs codes figés.
Seuls les types créés par l'utilisateur bénéficient de l'auto-génération.
2026-04-16 10:20:19 +00:00
dahoud
15479c0432 fix(types-org): fusionner MUTUELLE_EPARGNE + MUTUELLE_CREDIT → MUTUELLE unifié
Une mutuelle (MEC/COOPEC) fait TOUJOURS épargne ET crédit conjointement
dans le cadre réglementaire BCEAO/UEMOA. La séparation en deux types
n'avait pas de réalité terrain.

V18 corrigée :
- MUTUELLE_EPARGNE + MUTUELLE_CREDIT supprimés
- MUTUELLE ajouté : modules EPARGNE,CREDIT,FINANCE,LCB_FT (complet)
- COOPERATIVE enrichi : ajout EPARGNE + VOTES (réalité terrain — les coopératives
  ont des AG avec votes et proposent souvent de l'épargne à leurs membres)

Passe de 17 → 16 types d'organisation.
Le mapping mobile _mapTypeOrganisationBilling garde les anciens codes en fallback
pour rétrocompatibilité.
2026-04-16 10:13:29 +00:00
dahoud
5f12ab3406 fix(audit): PorteeAudit.GLOBAL → PLATEFORME + archiver docs obsolètes
- AuditService.logMembreDesactive : PorteeAudit.GLOBAL n'existe pas dans l'enum,
  remplacé par PLATEFORME (même sémantique — audit admin plateforme)
- docs/archive/ : archivé AUDIT_MIGRATIONS_PRECISE, CONSOLIDATION_MIGRATIONS_FINALE,
  NETTOYAGE_MIGRATIONS_RAPPORT, TESTS_CONNUS_EN_ECHEC, JACOCO_TESTS_MANQUANTS
- docs/FLYWAY_MIGRATIONS_GUIDE.md : consolidé depuis AUDIT_MIGRATIONS.md
2026-04-16 09:31:14 +00:00
dahoud
316e683c46 chore(gitignore): dédupliquer + ajouter Maven cache + credentials + .env
- Retrait du doublon du.exe.stackdump (était présent 2 fois)
- *.stackdump (générique pour crashes bash/cygwin)
- Maven lastUpdated + _remote.repositories (caches de pulls échoués)
- *-credentials.json + application-secrets.properties (secrets)
- .env + .env.* (env vars)
- .quarkus-dev-ui-history (dev mode UI)
- macOS (.AppleDouble, .LSOverride)
2026-04-15 23:20:14 +00:00
dahoud
4e1a6d4007 test: couverture Messaging + Versement + ContactPolicy + MemberBlock
Tests unitaires pour les nouveaux modules :
- Entity tests : ContactPolicyTest, ConversationParticipantTest, MemberBlockTest,
  VersementTest, VersementObjetTest
- Repository tests : ContactPolicyRepositoryTest, ConversationParticipantRepositoryTest,
  MemberBlockRepositoryTest, VersementRepositoryTest
- Resource tests : MessagingResourceTest, VersementResourceTest
- Service tests : MessagingServiceTest, VersementServiceTest
2026-04-15 20:24:33 +00:00
dahoud
2f7bb545d0 chore: pom.xml + application.properties + tests + gitignore
- pom.xml : mise à jour dépendances
- application.properties : ajustements config
- MembreServiceTest, EntityCoverageTest : tests mis à jour pour nouveautés
- .gitignore : ajout du.exe.stackdump (dump Windows bash)
2026-04-15 20:24:16 +00:00
dahoud
66151b4fd1 feat(dashboard): DashboardServiceImpl + KafkaEventConsumer mis à jour
- DashboardServiceImpl : stats enrichies
- KafkaEventConsumer : consommation events pour refresh stats temps réel
- BackupRecordRepository, SystemLogRepository : petits ajustements
2026-04-15 20:24:05 +00:00
dahoud
6ff85bd503 feat(wave): webhooks + redirect handler
- WebhookWave : entité pour logs webhooks Wave (idempotence + audit)
- WaveRedirectResource : endpoint de retour après paiement Wave
  (redirige vers l'app mobile avec le statut)
2026-04-15 20:23:58 +00:00
dahoud
e482ad5a4d feat(admin): KeycloakAdminHttpClient + AdminUserService amélioré
- KeycloakAdminHttpClient (nouveau) : client HTTP natif (java.net.http.HttpClient)
  pour contourner les problèmes de désérialisation avec RESTEasy sur certains
  endpoints Keycloak 26+ (bruteForceStrategy, cpuInfo inconnus).
  Utilise ObjectMapper avec FAIL_ON_UNKNOWN_PROPERTIES=false.
- AdminUserService : utilisation correcte de AdminUserServiceClient + AdminRoleServiceClient
  avec AdminServiceTokenHeadersFactory pour l'auth.
- ModuleAccessFilter : améliorations de la logique @RequiresModule.
2026-04-15 20:23:50 +00:00
dahoud
9a270995ee feat(system-config): persistance configuration système en DB
- Migration V29 : table system_config (key-value avec type/description)
- SystemConfigPersistence : entité pour stocker les paramètres système
- SystemConfigPersistenceRepository : findByKey + upsert
- SystemConfigService : lecture/écriture typée (String/Int/Bool) avec fallback defaults
- SystemResource : endpoints de config exposés aux SuperAdmins
2026-04-15 20:23:39 +00:00
dahoud
217021933e fix(paiement): rendre colonnes legacy nullables + refactor Paiement/PaiementObjet
Migrations :
- V25 : numero_transaction nullable dans paiements (legacy V1 NOT NULL bloquant INSERT)
- V26 : autres colonnes legacy NOT NULL V1 (type_paiement, statut_paiement, etc.)
  rendues nullables pour alignement avec l'entité Paiement

Refactor Paiement/PaiementObjet : mise à jour entités, repository, resource, service
pour cohérence avec le nouveau module Versement. Tests associés supprimés/ajustés.
2026-04-15 20:23:30 +00:00
dahoud
5d028a10bf feat(versement): nouveau module Versement (paiements rattachés à des objets)
- Entités : Versement, VersementObjet (lien polymorphique vers cotisation/adhesion/etc.)
- VersementRepository : requêtes par membre, org, période
- VersementResource : endpoints REST /api/versements
- VersementService : logique métier (validation, rattachement objets)
- Migration V27 : ajout numeroTelephone sur versements
2026-04-15 20:23:17 +00:00
dahoud
719d45e1fe feat(messaging): module messagerie unifié avec contact policies + member blocks
Refactor complet : fusion de Conversation + Message en un module Messaging unique
avec ContactPolicy (règles qui-peut-parler-à-qui) et MemberBlock (blocages utilisateur).

- Migration V28 : tables conversations/conversation_participants/messages/
  contact_policies/member_blocks
- Nouvelles entités : ContactPolicy, ConversationParticipant, MemberBlock
  (Conversation/Message mises à jour avec relations)
- Nouvelles repositories : ContactPolicyRepository, ConversationParticipantRepository,
  MemberBlockRepository
- MessagingResource (nouveau) remplace ConversationResource + MessageResource
- MessagingService (nouveau) remplace ConversationService + MessageService
  avec vérifications appartenance org + policies + blocages avant envoi
- Anciens fichiers Conversation/Message Resource/Service/Tests supprimés
2026-04-15 20:23:04 +00:00
dahoud
a650b372f1 chore: untrack target/ (déjà dans .gitignore mais tracké par erreur) 2026-04-15 20:17:37 +00:00
dahoud
aebf333421 chore(dev): revert IP LAN 192.168.1.13 → 192.168.1.145 2026-04-15 20:13:02 +00:00
dahoud
aa4350ffbb feat(members): desactiverMembre cascade complète (Keycloak, Kafka, audit, mono-admin)
Refactor de MembreService.desactiverMembre en 8 étapes transactionnelles :

1. GARDE-FOU mono-admin : refuse 409 Conflict si le membre est le seul
   ORGADMIN d'au moins une org (évite l'orphelinage).
2. DB : actif=false + statutCompte='DESACTIVE'.
3. Adhésions actives → SUSPENDU + décrément nombreMembres.
4. MembreRole (ORGADMIN, TRESORIER...) → actif=false, dateFin=today.
5. Notifications pending (EN_ATTENTE, ECHEC_TEMPORAIRE) → ANNULEE.
6. Keycloak (lions-user-manager) : user.enabled=false → login bloqué.
7. Kafka : publishMemberDeactivated(membre) sur unionflow.members.events
   → consumers peuvent réagir (comptes épargne, inscriptions, approvals, etc.)
8. AuditLog MEMBRE_DESACTIVE : opérateur, timestamp, compteurs (RGPD/compliance).

Côté liste :
- listerMembres/compterMembres : filtre actif=true par défaut (SuperAdmin).
- MembreRepository.findDistinctByOrganisationIdIn : idem pour OrgAdmin.

Services ajoutés :
- AuditService.logMembreDesactive
- KafkaEventProducer.publishMemberDeactivated
2026-04-15 20:12:55 +00:00