feat: WebSocket temps réel + Finance Workflow + corrections

- Task #6: WebSocket /ws/dashboard + Kafka events (5 topics)
  * Backend: KafkaEventProducer, KafkaEventConsumer
  * Mobile: WebSocketService (reconnection, heartbeat, typed events)
  * DashboardBloc: Auto-refresh depuis WebSocket events

- Finance Workflow: approbations + budgets (backend + mobile)
  * Backend: entities, services, resources, migrations Flyway V6
  * Mobile: features finance_workflow complète avec BLoC

- Corrections DI: interfaces IRepository partout
  * IProfileRepository, IOrganizationRepository, IMembreRepository
  * GetIt configuré avec @injectable

- Spec-Kit: constitution + templates mis à jour
  * .specify/memory/constitution.md enrichie
  * Templates agent, plan, spec, tasks, checklist

- Nettoyage: fichiers temporaires supprimés

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 02:12:17 +00:00
parent bbc409de9d
commit e8ad874015
635 changed files with 58160 additions and 20674 deletions

View File

@@ -0,0 +1,151 @@
# Audit Spec-Kit vs code source existant
**Date** : 2026-03-08
**Objectif** : Vérifier la cohérence du Spec-Kit avec le code et identifier les points à corriger ou documenter pour que tout se passe correctement.
---
## 1. Résumé exécutif
| Domaine | Statut | Commentaire |
|--------|--------|-------------|
| Scripts PowerShell | OK | Chemins et logique cohérents avec la racine du dépôt. |
| Branche / répertoire feature | À documenter | Sur `main`/`master`, les commandes plan/tasks/implement échouent si `specs/<branche>` nexiste pas. |
| Inventaire vs code mobile | Globalement OK | Quelques précisions utiles (dashboards Consultant/HrManager, DI épargne). |
| Fichiers et chemins Spec-Kit | OK | Tous les artefacts listés existent. |
| Constitution / baseline | OK | Références et contenu alignés. |
**Verdict** : Le Spec-Kit est aligné avec le code. Pour que tout se passe bien, il faut **être sur une branche feature (ex. `001-mutuelles-anti-blanchiment`) ou définir `SPECIFY_FEATURE`** avant dexécuter `/speckit.plan`, `/speckit.tasks` ou `/speckit.implement`. Aucune modification de code nest requise ; des précisions en documentation sont recommandées.
---
## 2. Scripts PowerShell
### 2.1 Racine du dépôt (Get-RepoRoot)
- **Fichier** : `.specify/scripts/powershell/common.ps1`
- **Comportement** : À partir de `$PSScriptRoot` (répertoire du script appelant, en pratique `.specify/scripts/powershell`), remonte de trois niveaux puis cherche un répertoire contenant `.specify`. Retourne ce répertoire (= racine du dépôt `unionflow/`).
- **Vérification** : Lorsque `check-prerequisites.ps1` est exécuté depuis `unionflow/`, il charge `common.ps1` depuis `.specify/scripts/powershell/` ; `Get-RepoRoot` remonte bien vers `unionflow/` et trouve `.specify`. **OK.**
### 2.2 Chemins dérivés (Get-FeaturePathsEnv)
- **FEATURE_DIR** = `Join-Path $RepoRoot "specs/$Branch"` avec `$Branch` = branche Git courante ou variable denvironnement `SPECIFY_FEATURE`.
- **Conséquence** : Si la branche est `master` (ou `main`), alors `FEATURE_DIR` = `specs/master` (ou `specs/main`). Ce répertoire nexiste pas dans le dépôt.
- **Comportement observé** : `check-prerequisites.ps1 -Json` exécuté depuis `unionflow/` avec branche `master` retourne :
`ERROR: Feature directory not found: ...\specs\master`. **Comportement attendu** : les commandes plan / tasks / implement supposent un répertoire de feature existant.
- **Recommandation** : Documenter clairement dans `SPEC-KIT.md` et/ou dans les commandes Cursor que :
- pour **plan**, **tasks**, **implement** : il faut être sur une branche de type `00X-nom` **ou** définir `SPECIFY_FEATURE=00X-nom` (ex. `001-mutuelles-anti-blanchiment`) ;
- pour **specify** : la commande crée la branche et le répertoire `specs/00X-nom/`, donc pas de prérequis de répertoire.
### 2.3 Fichiers et chemins utilisés par les scripts
| Script | Fichiers / chemins utilisés | Existence |
|--------|-----------------------------|-----------|
| check-prerequisites.ps1 | common.ps1, FEATURE_DIR, IMPL_PLAN, TASKS, RESEARCH, DATA_MODEL, CONTRACTS_DIR, QUICKSTART | OK (chemins dérivés de FEATURE_DIR) |
| setup-plan.ps1 | common.ps1, FEATURE_DIR, REPO_ROOT, `.specify/templates/plan-template.md` | OK (template présent) |
| create-new-feature.ps1 | Find-RepositoryRoot (marqueur .specify), specs/, template spec | OK |
| update-agent-context.ps1 | common.ps1, IMPL_PLAN, REPO_ROOT, `.specify/templates/agent-file-template.md` | OK |
Aucun chemin en dur ne pointe vers un fichier ou dossier absent.
---
## 3. Inventaire vs code source (mobile)
### 3.1 Routes et navigation
- **Inventaire** : MaterialApp + `Map<String, WidgetBuilder>`, routes `/`, `/login`, `/dashboard` ; pas de go_router pour la racine.
- **Code** : `app/router/app_router.dart` définit bien un `Map` avec `/`, `/dashboard`, `/login` ; pas dusage de go_router pour ces routes. **OK.**
### 3.2 Structure lib/
- **Inventaire** : `app/`, `core/` (config, constants, di, error, l10n, network, storage, usecases, utils, navigation), `features/<nom>/`, `shared/`.
- **Code** : Présence de `app/`, `core/` (avec les sous-dossiers mentionnés), `features/`, `shared/`. Fichiers cités (`environment.dart`, `api_client.dart`, `injection.dart`, `injection_container.dart`, `register_module.dart`, `main_navigation_layout.dart`, `more_page.dart`) existent. **OK.**
### 3.3 Features listées
- Les 21 features listées dans linventaire (about, adhesions, admin, authentication, backup, contributions, dashboard, epargne, events, explore, feed, help, logs, members, notifications, organizations, profile, reports, settings, solidarity) correspondent à des répertoires sous `lib/features/`. **OK.**
### 3.4 Dashboards par rôle
- **Inventaire** : « SuperAdmin, OrgAdmin, Moderator, ActiveMember, SimpleMember, Visitor, Consultant, HrManager ».
- **Code** :
- `UserRole` (user_role.dart) ne contient que : superAdmin, orgAdmin, moderator, activeMember, simpleMember, visitor (6 rôles).
- `main_navigation_layout.dart` ne branche que ces 6 rôles vers un dashboard.
- Les widgets `ConsultantDashboard` et `HrManagerDashboard` existent (fichiers `consultant_dashboard.dart`, `hr_manager_dashboard.dart`) mais ne sont pas utilisés dans le switch de `MainNavigationLayout`.
- **Recommandation** : Préciser dans linventaire que les dashboards « par rôle » effectivement utilisés dans la navigation principale sont les 6 rôles de `UserRole`, et que Consultant/HrManager existent comme écrans mais ne sont pas assignés à un rôle dans ce layout (ou les retirer de la liste des dashboards « par rôle » pour éviter toute ambiguïté).
### 3.5 Injection de dépendances (DI)
- **Inventaire** : Liste des types enregistrés dans `injection.config.dart` ; mention que `CompteEpargneRepository` et `TransactionEpargneRepository` ne sont pas enregistrés.
- **Code** : `injection.config.dart` enregistre bien les types listés (ApiClient, KeycloakAuthService, AuthBloc, ProfileRepository, MembreRepository, etc.). Aucun enregistrement pour `CompteEpargneRepository` ni `TransactionEpargneRepository`. **OK.**
- **Risque** : `EpargnePage` et `DepotEpargneDialog` utilisent `GetIt.I<CompteEpargneRepository>()` et `GetIt.I<TransactionEpargneRepository>()`. Sans enregistrement, lécran épargne provoquera une exception au runtime. Linventaire le signale déjà ; cest un point de suivi fonctionnel (enregistrement ou autre moyen dinjection), pas un écart Spec-Kit / code.
### 3.6 Rôles utilisateur (mobile)
- **Inventaire** : `UserRole` : superAdmin, orgAdmin, moderator, activeMember, simpleMember, visitor.
- **Code** : Identique dans `user_role.dart`. **OK.**
---
## 4. Artefacts Spec-Kit (fichiers et dossiers)
Vérification que chaque élément référencé dans `SPEC-KIT.md` et dans linventaire (section 5) existe :
| Artefact | Présent |
|----------|---------|
| SPEC-KIT.md (racine) | Oui |
| CONSTITUTION.md (racine) | Oui |
| .specify/memory/constitution.md | Oui |
| .specify/memory/inventaire-code.md | Oui |
| .specify/scripts/powershell/common.ps1 | Oui |
| .specify/scripts/powershell/check-prerequisites.ps1 | Oui |
| .specify/scripts/powershell/setup-plan.ps1 | Oui |
| .specify/scripts/powershell/create-new-feature.ps1 | Oui |
| .specify/scripts/powershell/update-agent-context.ps1 | Oui |
| .specify/templates/spec-template.md | Oui |
| .specify/templates/plan-template.md | Oui |
| .specify/templates/tasks-template.md | Oui |
| .specify/templates/checklist-template.md | Oui |
| .specify/templates/constitution-template.md | Oui |
| .specify/templates/agent-file-template.md | Oui |
| .cursor/commands/speckit.*.md (9 fichiers) | Oui |
| .cursor/rules/unionflow-spec-kit.mdc | Oui |
| .cursor/rules/unionflow-backend.mdc | Oui |
| .cursor/rules/unionflow-mobile.mdc | Oui |
| specs/000-unionflow-baseline/spec.md | Oui |
| specs/001-mutuelles-anti-blanchiment/spec.md, plan.md, tasks.md | Oui |
Aucun fichier ou dossier référencé nest manquant.
---
## 5. Commandes Cursor et scripts
- Les commandes qui appellent un script ne référencent plus que le script PowerShell (pas de script Bash). Les chemins indiqués sont relatifs à la racine du dépôt (ex. `.specify/scripts/powershell/check-prerequisites.ps1 -Json`). **OK.**
- Les commandes sont conçues pour être exécutées avec le répertoire de travail = racine du dépôt (unionflow/). Cest cohérent avec lusage dans Cursor. **OK.**
---
## 6. Constitution et baseline
- **CONSTITUTION.md** (racine) et **.specify/memory/constitution.md** : tous deux présents ; la doc indique quils doivent rester synchronisés. **OK.**
- **Section 13 (Mobile)** : La constitution décrit `core/config/environment.dart`, `AppConfig.initialize()`, Environment, etc., en phase avec le code. **OK.**
- **specs/000-unionflow-baseline/spec.md** : Décrit les modules, le workflow Spec-Kit, linventaire consolidé et les artefacts Spec-Kit. Aligné avec létat actuel. **OK.**
---
## 7. Actions recommandées (sans changement de code)
1. **Documenter le prérequis branche / SPECIFY_FEATURE**
Dans `SPEC-KIT.md` (et éventuellement dans les descriptions des commandes plan, tasks, implement), ajouter explicitement que :
- pour **plan**, **tasks**, **implement** : la branche courante doit être une branche feature `00X-nom` **ou** la variable denvironnement `SPECIFY_FEATURE` doit être définie (ex. `001-mutuelles-anti-blanchiment`) ;
- le répertoire `specs/<branche>` doit exister (créé par exemple par `/speckit.specify` ou par création manuelle).
2. **Précision inventaire sur les dashboards**
Dans la section 4.2 (dashboard), préciser que les 6 rôles utilisés dans `MainNavigationLayout` sont ceux de `UserRole` (superAdmin, orgAdmin, moderator, activeMember, simpleMember, visitor), et que ConsultantDashboard et HrManagerDashboard existent comme widgets mais ne sont pas branchés dans ce layout.
3. **Rappel DI épargne**
Conserver dans linventaire la mention que CompteEpargneRepository et TransactionEpargneRepository ne sont pas enregistrés dans GetIt, et que lécran épargne nécessitera un enregistrement ou une autre forme dinjection pour fonctionner.
Aucune modification du code source nest nécessaire pour que le Spec-Kit soit cohérent avec le dépôt ; les actions ci-dessus sont des clarifications documentaires pour que lusage des commandes et linterprétation de linventaire soient sans ambiguïté.

View File

@@ -2,6 +2,7 @@
**Feature Branch**: `000-unionflow-baseline`
**Created**: 2026-02-27
**Updated**: 2026-03-08
**Status**: Baseline documentant l'état actuel
**Type**: Brownfield / Documentation
@@ -9,6 +10,8 @@
Ce document capture l'état actuel du projet UnionFlow pour le Spec-Driven Development. UnionFlow est une plateforme de gestion d'associations, clubs et organisations à but non lucratif, et de **gestion des mutuelles d'épargne et de financement**.
**Référence anti-hallucination** : linventaire détaillé du code (packages API, migrations, features mobile, routes) est dans `.specify/memory/inventaire-code.md`. Toute spécification ou implémentation doit sy aligner ; ne pas inventer de packages, endpoints ou fichiers non listés.
## Architecture actuelle
### Modules
@@ -48,6 +51,24 @@ unionflow/
2. **Specs**: `specs/001-nom-court/spec.md`, `plan.md`, `tasks.md`
3. **Commandes Cursor**: `/speckit.specify`, `/speckit.plan`, `/speckit.tasks`, `/speckit.implement`
## Inventaire consolidé
- **API** : ~210 fichiers Java en `unionflow-server-api/src/main/java` (dto.*, enums.*, service.dashboard, validation). Voir `.specify/memory/inventaire-code.md` pour la liste des packages et conventions.
- **Impl** : Migrations Flyway V1.2 à V3.4 listées dans linventaire ; code métier (entity, service, resource, mapper) selon CONSTITUTION.
- **Mobile** : Routes `/`, `/login`, `/dashboard` ; navigation par onglets (Dashboard, Membres, Événements, Plus) ; features about, adhesions, admin, authentication, backup, contributions, dashboard, epargne, events, explore, feed, help, logs, members, notifications, organizations, profile, reports, settings, solidarity. Détail à jour dans `.specify/memory/inventaire-code.md`.
## Artefacts Spec-Kit (référence complète)
- **Racine** : `SPEC-KIT.md` (vue densemble), `CONSTITUTION.md` (principes).
- **.specify/memory/** : `constitution.md`, `inventaire-code.md` (référence anti-hallucination).
- **.specify/scripts/powershell/** : `common.ps1`, `check-prerequisites.ps1`, `setup-plan.ps1`, `create-new-feature.ps1`, `update-agent-context.ps1`. Aucun script Bash.
- **.specify/templates/** : `spec-template.md`, `plan-template.md`, `tasks-template.md`, `checklist-template.md`, `constitution-template.md`, `agent-file-template.md`.
- **.cursor/commands/** : `speckit.constitution.md`, `speckit.specify.md`, `speckit.plan.md`, `speckit.tasks.md`, `speckit.implement.md`, `speckit.clarify.md`, `speckit.checklist.md`, `speckit.analyze.md`, `speckit.taskstoissues.md`.
- **.cursor/rules/** : `unionflow-spec-kit.mdc` (always), `unionflow-backend.mdc`, `unionflow-mobile.mdc`.
- **specs/** : `000-unionflow-baseline/spec.md` (ce fichier) ; par feature `00X-nom/` : `spec.md`, `plan.md`, `tasks.md`, optionnellement `research.md`, `data-model.md`, `quickstart.md`, `contracts/`, `checklists/`.
En cas de divergence entre documentation et code, **le code fait foi** ; mettre à jour linventaire en conséquence.
## Commandes utiles
```powershell

View File

@@ -0,0 +1,96 @@
# Plan d'implémentation : Gestion des mutuelles orientée anti-blanchiment (LCB-FT)
**Branche** : `001-mutuelles-anti-blanchiment` | **Date** : 2026-03-08 | **Spec** : [spec.md](./spec.md)
**Entrée** : Spécification dans `specs/001-mutuelles-anti-blanchiment/spec.md`
## Résumé
Mise en conformité LCB-FT/BCEAO/OHADA des flux mutuelles (épargne, crédit, paiements) : traçabilité (origine des fonds, justification), seuils configurables, niveau KYC membre, audit et alertes. Livrables dans lordre : API → Migrations → Impl Quarkus → Mobile (écrans mutuelles + affichage KYC fiche membre).
## Contexte technique
**Langage/Version** : Java 17 (backend), Dart 3 / Flutter ^3.5.3 (mobile)
**Dépendances principales** : Quarkus 3.15.1, Panache, MapStruct (backend) ; go_router, flutter_bloc, get_it, dio (mobile)
**Stockage** : PostgreSQL 15+ (prod), H2 (dev/test) ; Flyway pour les migrations
**Tests** : JUnit/QuarkusTest (backend, 100 % JaCoCo), bloc_test/mockito (mobile)
**Plateforme cible** : Serveur Linux (backend), Android / iOS (mobile)
**Type de projet** : Backend API + Impl Quarkus + App mobile Flutter
**Contraintes** : Pas de données fictives ; seuils LCB-FT configurables (organisation/plateforme)
**Échelle / périmètre** : Extension du module mutuelles existant (API, BDD, services, écrans mobile épargne/crédit et fiche membre)
## Contrôle constitution
- **DDD** : Resources → Services → Repositories ; pas daccès direct aux repositories depuis les resources.
- **API/Impl** : Nouveaux champs et DTOs dans `unionflow-server-api` ; impl dans `unionflow-server-impl-quarkus`.
- **Sécurité** : Keycloak OIDC ; rôles existants ; pas de contournement des contrôles LCB-FT.
- **RGPD / Audit** : Audit trail (creePar, modifiePar, dates) ; conservation 10 ans pour audit_logs ; extension aux opérations mutuelles.
- **Mobile** : Données uniquement via API ; pas de listes en dur ; seuil LCB-FT fourni par API/config.
## Structure du projet
### Documentation (cette feature)
```text
specs/001-mutuelles-anti-blanchiment/
├── spec.md # Spécification fonctionnelle (existant)
├── plan.md # Ce fichier
├── tasks.md # À générer via /speckit.tasks
└── contracts/ # (optionnel) Endpoints impactés
```
### Code source (monorepo unionflow)
```text
unionflow/
├── unionflow-server-api/ # DTOs, enums LCB-FT (origineFonds, KYC, seuils)
├── unionflow-server-impl-quarkus/ # Migrations, services, resources, validation seuils
│ └── src/main/resources/db/migration/ # V3.4+ LCB-FT si non présent
├── unionflow-mobile-apps/ # Flutter
│ └── lib/
│ ├── core/constants/ # lcb_ft_constants (seuil par défaut, à compléter par API)
│ └── features/
│ ├── epargne/ # Dépôt/retrait/transfert + origine + pièce justificative si seuil
│ └── members/ # Fiche membre : statut KYC, date vérification identité (lecture)
```
**Décision de structure** : On sappuie sur la structure existante (inventaire `.specify/memory/inventaire-code.md`). La feature `epargne` mobile existe déjà ; on complète les champs LCB-FT et laffichage KYC dans la fiche membre.
## Ordre des livrables (aligné spec §5)
| Ordre | Livrable | Contenu principal |
|-------|----------|-------------------|
| 1 | Spec + inventaire | Fait (spec.md) |
| 2 | **API** (unionflow-server-api) | Champs `origineFonds`, `pieceJustificativeId` (transaction épargne) ; enums `NiveauVigilanceKyc`, `StatutKyc` ; champs membre `dateVerificationIdentite` ; DTOs paramètres LCB-FT / seuils ; extension intentions paiement (EPARGNE_DEPOT, etc. + origineFonds, justificationLcbFt) |
| 3 | **Migrations Flyway** | Colonnes membres/KYC ; transaction_epargne (origine_fonds, piece_justificative_id) ; intentions_paiement (origine_fonds, justification_lcb_ft) ; table paramètres LCB-FT (seuils) |
| 4 | **Impl Quarkus** | Règles de validation (seuil → exiger origineFonds) ; audit des opérations mutuelles ; ressource/config pour seuils ; éventuelle ressource « alertes LCB-FT » |
| 5 | **Mobile** | Écrans mutuelles : origine des fonds + pièce justificative (upload) si montant ≥ seuil (seuil depuis API/config) ; fiche membre : affichage statut KYC et date vérification identité (lecture seule) |
## Phases dimplémentation proposées
### Phase 1 API et contrat
- Ajout/extension des DTOs et enums dans `unionflow-server-api` (spec §3.1).
- Mise à jour de linventaire après chaque ajout.
### Phase 2 Persistance
- Création ou complément des migrations Flyway (spec §3.2) ; pas de modification de migrations existantes.
### Phase 3 Règles métier backend
- Services : validation seuil, obligation origineFonds / pièce si montant ≥ seuil ; audit ; optionnel : alertes LCB-FT (spec §3.3).
### Phase 4 Mobile
- **Épargne** : Sassurer que dépôt/retrait/transfert utilisent bien lAPI (origine des fonds, pièce justificative si seuil) ; seuil de préférence fourni par lAPI/config plutôt quen dur.
- **Fiche membre** : Affichage en lecture seule du statut KYC et de la date de vérification didentité (données provenant de lAPI membre).
## Références
- **Constitution** : `.specify/memory/constitution.md` (sections 14, 8, 13).
- **Inventaire** : `.specify/memory/inventaire-code.md` (packages API, migrations, features mobile).
- **Baseline** : `specs/000-unionflow-baseline/spec.md`.
## Suivi des écarts à la constitution
Aucun écart identifié ; le plan reste aligné avec la constitution et le baseline.

View File

@@ -0,0 +1,151 @@
# Spécification : Gestion des mutuelles orientée anti-blanchiment (LCB-FT)
**Feature Branch** : `001-mutuelles-anti-blanchiment`
**Créé** : 2026-02-28
**Statut** : Spécification
**Type** : Extension métier (alignement LCB-FT / BCEAO/OHADA)
## Contexte
UnionFlow gère des mutuelles d'épargne et de crédit. Les flux de fonds (dépôts, retraits, transferts, crédits) doivent être traçables et conformes aux exigences de **lutte contre le blanchiment des capitaux et le financement du terrorisme (LCB-FT)** et aux bonnes pratiques BCEAO/OHADA.
Ce document décrit létat actuel du backend (API + impl) pour les mutuelles, puis les extensions proposées pour une gestion orientée anti-blanchiment, **sans données fictives**.
---
## 1. État actuel (inventaire)
### 1.1 API unionflow-server-api
**Mutuelles épargne**
- **dto.mutuelle.epargne**
- `CompteEpargneRequest` : membreId, organisationId, typeCompte, notesOuverture
- `CompteEpargneResponse` : id, membreId, organisationId, numeroCompte, typeCompte, soldeActuel, soldeBloque, statut, dateOuverture, dateDerniereTransaction, description
- `TransactionEpargneRequest` : compteId, typeTransaction, montant, compteDestinationId, **motif**
- `TransactionEpargneResponse` : compteId, type, montant, soldeAvant/Apres, motif, dateTransaction, operateurId, referenceExterne, statutExecution
- **enums.mutuelle.epargne** : TypeTransactionEpargne (DEPOT, RETRAIT, TRANSFERT_ENTRANT/SORTANT, PAIEMENT_INTERETS, etc.), StatutCompteEpargne, TypeCompteEpargne
**Mutuelles crédit**
- **dto.mutuelle.credit**
- `DemandeCreditRequest` : membreId, typeCredit, montantDemande, dureeMois, compteLieId, **justificationDetaillee**, documentIds, garantiesProposees
- `DemandeCreditResponse` : numeroDossier, membreId, montantDemande/Approuve, echeancier, statut, notesComite, etc.
- `GarantieDemandeDTO`, `EcheanceCreditDTO`
- **enums.mutuelle.credit** : StatutDemandeCredit, TypeCredit, TypeGarantie, StatutEcheanceCredit
**Paiements / intentions**
- **dto.paiement** : CreatePaiementRequest (numeroReference, montant, codeDevise, methodePaiement, commentaire, membreId), Wave DTOs
- **intentions_paiement** (V2.3) : utilisateur_id, organisation_id, montant_total, code_devise, type_objet, statut, objets_cibles, wave_* — pas de champ dédié « origine des fonds » ou « justification LCB-FT »
**Membres (KYC)**
- `CreateMembreRequest` : **typeIdentite**, **numeroIdentite** (déjà présents), nom, prénom, email, téléphone, dateNaissance, profession, nationalite, statutMatrimonial
**Audit**
- V2.9 : audit_logs avec organisation_id, portee (ORGANISATION | PLATEFORME), conservation 10 ans (BCEAO/OHADA/Fiscalité)
### 1.2 Base de données (migrations)
- **paiements** : reference, montant, devise, methode_paiement, statut, membre_id, organisation_id — pas dorigine des fonds ni de seuil LCB-FT
- **intentions_paiement** : type_objet (COTISATION, ADHESION, EVENEMENT, ABONNEMENT_UNIONFLOW) — pas dEPARGNE ni CREDIT ni champs LCB-FT
- **membres** : pas de niveau de vigilance (KYC simplifié / renforcé) ni de date de vérification didentité
- **audit_logs** : portee, organisation_id — adapté pour traçabilité
### 1.3 Mobile (unionflow-mobile-apps)
- Pas de feature dédiée « mutuelles » (épargne/crédit) dans les écrans listés ; contributions, adhesions, solidarité, dashboard existent.
- Les écrans mutuelles (sils sont ajoutés) devront afficher uniquement des données réelles (API), avec champs obligatoires pour origine des fonds / justification lorsque le backend les exigera.
---
## 2. Objectifs orientés anti-blanchiment
1. **Traçabilité** : chaque opération significative (dépôt, retrait, transfert, déblocage crédit) liée à un membre identifié, avec origine des fonds ou motif explicite.
2. **Seuils** : au-dessus dun montant configurable (ex. 500 000 XOF / 1 000 000 XOF), renforcement des contrôles (justification obligatoire, validation, éventuelle déclaration).
3. **Vigilance** : niveau KYC membre (simplifié / renforcé), date de vérification didentité, lien avec éligibilité aux opérations.
4. **Alertes** : transactions inhabituelles (montant, fréquence, motif) et dépassement de seuil en vue dun contrôle manuel ou déclaration.
5. **Conservation** : conservation des justificatifs et journaux conforme aux exigences (déjà 10 ans pour audit_logs ; à étendre aux pièces et champs LCB-FT).
---
## 3. Propositions dextension (sans données fictives)
### 3.1 API Nouveaux champs et contrats
**TransactionEpargneRequest (extension)**
- `origineFonds` (String, optionnel) : libellé court de lorigine des fonds (ex. « Salaire », « Vente », « Héritage ») — obligatoire au-dessus du seuil configuré.
- `pieceJustificativeId` (UUID, optionnel) : référence vers une pièce jointe (document) pour les opérations au-dessus du seuil.
**TransactionEpargneResponse (extension)**
- Conserver les champs existants ; ajouter éventuellement `origineFonds`, `pieceJustificativeId` en lecture pour traçabilité.
**DemandeCreditRequest (déjà bien orienté)**
- Déjà : justificationDetaillee, documentIds, garantiesProposees.
- Optionnel : `origineFondsRemboursement` (String) pour indiquer la source prévue du remboursement (cohérence LCB-FT).
**Intentions de paiement / Paiements**
- Étendre `type_objet` (ou équivalent API) pour inclure **EPARGNE_DEPOT**, **EPARGNE_RETRAIT**, **CREDIT_REMBOURSEMENT** si les flux passent par le hub Wave.
- Ajouter dans le DTO dintention ou de paiement : `origineFonds` (String, optionnel), `justificationLcbFt` (String, optionnel) — obligatoires au-dessus du seuil.
**Membre / KYC**
- Ajouter en API (et en base) :
- `niveauVigilanceKyc` : enum (SIMPLIFIE | RENFORCE).
- `dateVerificationIdentite` (LocalDate, optionnel).
- `statutKyc` : enum (NON_VERIFIE | EN_COURS | VERIFIE | REFUSE) pour piloter léligibilité aux opérations.
**Configuration organisation / plateforme**
- Seuils LCB-FT configurables (par organisation ou globaux) : montant au-dessus duquel justification obligatoire, montant au-dessus duquel validation manuelle obligatoire (ex. 500k / 1M XOF). À exposer via config ou table `parametres_organisation` / `parametres_plateforme`.
### 3.2 Base de données
- **membres** (ou table dédiée `membre_kyc`) : colonnes `niveau_vigilance_kyc`, `date_verification_identite`, `statut_kyc`.
- **transaction_epargne** (si table dédiée) ou table des mouvements : colonnes `origine_fonds`, `piece_justificative_id`, `seuil_lcb_ft_atteint` (booléen).
- **intentions_paiement** : colonnes `origine_fonds`, `justification_lcb_ft` (TEXT).
- **parametres** : table ou colonnes pour seuils LCB-FT (montant_seuil_justification, montant_seuil_validation_manuelle, code_devise).
### 3.3 Règles métier (impl Quarkus)
- Lors de la création dune transaction épargne (dépôt, retrait, transfert) : si montant >= seuil configuré, exiger `origineFonds` (et éventuellement `pieceJustificativeId`) ; sinon rejet (400) avec message clair.
- Crédit : conserver justification détaillée + documents ; optionnellement exiger `dateVerificationIdentite` à jour pour le membre avant déblocage.
- Enregistrement systématique dans `audit_logs` des opérations mutuelles (épargne/crédit) avec portee ORGANISATION et détails (montant, type, membre, seuil franchi).
- Alertes : création dévénements ou entrées « alerte LCB-FT » (table dédiée ou type daudit) pour dépassement de seuil, motif vide au-dessus du seuil, ou éventuellement pattern inhabituel (à définir en phase 2).
### 3.4 Mobile
- Formulaires de dépôt/retrait/transfert épargne : champs **Origine des fonds** et **Pièce justificative** (upload) rendus obligatoires lorsque le montant saisi dépasse le seuil (seuil fourni par lAPI ou la config).
- Pas daffichage de données fictives : listes et détails mutuelles = appels API uniquement.
- Fiche membre : affichage du statut KYC et de la date de vérification didentité (lecture seule si pas de droit de modification).
---
## 4. Conformité et références
- **BCEAO** : directives sur les systèmes financiers décentralisés et la lutte contre le blanchiment.
- **OHADA** : conservation des preuves et traçabilité des opérations.
- **LCB-FT** : identification, vigilance, traçabilité, déclaration des opérations suspectes (la déclaration aux autorités reste hors scope applicatif direct ; le système prépare les données et alertes).
---
## 5. Livrables proposés (ordre recommandé)
1. **Spec + inventaire** (ce document) — fait.
2. **API (unionflow-server-api)** : ajout des champs et enums (origineFonds, niveauVigilanceKyc, statutKyc, dateVerificationIdentite, seuils) dans les DTOs existants ; nouveaux DTOs ou champs pour paramètres LCB-FT.
3. **Migrations Flyway** : nouvelles colonnes membres/KYC, transaction_epargne/intentions_paiement, table paramètres LCB-FT.
4. **Impl Quarkus** : règles de validation (seuils), enregistrement audit, éventuelle table/ressource « alertes LCB-FT ».
5. **Mobile** : écrans mutuelles (épargne/crédit) avec champs obligatoires selon seuil, sans données fictives.
---
## 6. Règle anti-hallucination
- Toute nouvelle classe, colonne ou endpoint doit être ajoutée dabord dans **unionflow-server-api** (ou dans ce spec avec référence explicite au fichier), puis reflétée dans linventaire `.specify/memory/inventaire-code.md`.
- Aucune donnée fictive en production : pas de listes en dur, pas de mock de données métier dans les écrans ou les réponses API.

View File

@@ -0,0 +1,100 @@
# Tâches : Gestion des mutuelles orientée anti-blanchiment (LCB-FT)
**Entrée** : `specs/001-mutuelles-anti-blanchiment/spec.md`, `plan.md`
**Prérequis** : plan.md, spec.md
**Ordre dexécution** : Respecter strictement lordre des phases (API → Migrations → Impl → Mobile). Les tâches mobile ne doivent être traitées quaprès les tâches backend correspondantes (ou en parallèle si lAPI est déjà disponible).
---
## Format : `[ID] [P?] Description`
- **[P]** : Peut sexécuter en parallèle (fichiers différents, pas de dépendances).
- Les chemins sont relatifs à la racine du dépôt `unionflow/`.
---
## Phase 1 : API (unionflow-server-api)
**Objectif** : Ajouter les champs et enums LCB-FT dans lAPI (spec §3.1).
- [ ] T001 [P] Étendre `TransactionEpargneRequest` (ou équivalent) avec `origineFonds` (String, optionnel), `pieceJustificativeId` (UUID, optionnel) si ce nest pas déjà fait — `unionflow-server-api/.../dto/mutuelle/epargne/`
- [ ] T002 [P] Étendre `TransactionEpargneResponse` avec `origineFonds`, `pieceJustificativeId` en lecture si nécessaire
- [ ] T003 [P] Ajouter en API les enums `NiveauVigilanceKyc`, `StatutKyc` (ex. `enums.membre`) et champs membre : `niveauVigilanceKyc`, `dateVerificationIdentite`, `statutKyc` (DTOs membre)
- [ ] T004 [P] Étendre les DTOs dintentions de paiement / paiement avec `origineFonds`, `justificationLcbFt` et étendre `type_objet` pour EPARGNE_DEPOT, EPARGNE_RETRAIT, CREDIT_REMBOURSEMENT si prévu par la spec
- [ ] T005 [P] Ajouter ou étendre le contrat (DTO / config) pour les paramètres LCB-FT (seuils : montant justification, montant validation manuelle, devise) — ex. `parametres_organisation` / `parametres_plateforme`
- [ ] T006 Mettre à jour `.specify/memory/inventaire-code.md` avec les nouveaux DTOs/enums/champs API
**Jalon** : API prête pour impl et mobile (contrats stables).
---
## Phase 2 : Migrations Flyway (unionflow-server-impl-quarkus)
**Objectif** : Schéma BDD aligné avec la spec §3.2 (sans modifier les migrations existantes).
- [ ] T007 Vérifier ou créer la migration LCB-FT : colonnes membres (ou table membre_kyc) `niveau_vigilance_kyc`, `date_verification_identite`, `statut_kyc`
- [ ] T008 Vérifier ou créer les colonnes `origine_fonds`, `piece_justificative_id` (et si besoin `seuil_lcb_ft_atteint`) sur la table des transactions épargne
- [ ] T009 Vérifier ou créer les colonnes `origine_fonds`, `justification_lcb_ft` sur la table intentions_paiement
- [ ] T010 Vérifier ou créer la table ou colonnes pour les paramètres LCB-FT (seuils : montant_seuil_justification, montant_seuil_validation_manuelle, code_devise)
- [ ] T011 Mettre à jour linventaire avec le numéro et le contenu de la migration LCB-FT
**Jalon** : Schéma BDD prêt pour limpl des services.
---
## Phase 3 : Implémentation Quarkus (unionflow-server-impl-quarkus)
**Objectif** : Règles métier, validation des seuils, audit (spec §3.3).
- [ ] T012 Implémenter la lecture des paramètres LCB-FT (seuils) depuis la BDD ou la config (organisation / plateforme)
- [ ] T013 Dans le service de transaction épargne : si montant ≥ seuil configuré, exiger `origineFonds` (et éventuellement `pieceJustificativeId`) ; sinon rejet 400 avec message clair
- [ ] T014 Enregistrer dans `audit_logs` les opérations mutuelles (épargne/crédit) avec portee ORGANISATION et détails (montant, type, membre, seuil franchi)
- [ ] T015 (Optionnel) Crédit : exiger ou vérifier `dateVerificationIdentite` à jour pour le membre avant déblocage selon la spec
- [ ] T016 (Optionnel) Créer la ressource ou le type dévénement « alertes LCB-FT » pour dépassement de seuil / motif vide (spec §3.3)
- [ ] T017 Exposer un endpoint ou une config (ex. paramètres organisation) pour que le mobile récupère le seuil LCB-FT (montant au-dessus duquel origine des fonds obligatoire)
**Jalon** : Backend LCB-FT opérationnel et consommable par le mobile.
---
## Phase 4 : Mobile (unionflow-mobile-apps)
**Objectif** : Écrans mutuelles conformes LCB-FT (origine des fonds, pièce justificative si seuil) ; fiche membre avec statut KYC et date de vérification didentité (spec §3.4).
### 4.1 Épargne Seuil et champs LCB-FT
- [ ] T018 Récupérer le seuil LCB-FT depuis lAPI (paramètres organisation) ou la config ; utiliser ce seuil dans les dialogs (dépôt/retrait/transfert) au lieu ou en complément de `lcb_ft_constants.dart`
- [ ] T019 Sassurer que les formulaires de dépôt, retrait et transfert épargne affichent et envoient `origineFonds` (obligatoire si montant ≥ seuil) — `lib/features/epargne/presentation/widgets/` (ex. `DepotEpargneDialog`, retrait, transfert)
- [ ] T020 Ajouter la saisie et lupload de la pièce justificative dans les dialogs épargne lorsque le montant ≥ seuil ; envoyer `pieceJustificativeId` dans `TransactionEpargneRequest` après upload
- [ ] T021 Afficher un message derreur clair côté mobile si lAPI retourne 400 (ex. origine des fonds manquante au-dessus du seuil)
**Jalon** : Flux épargne mobile conformes LCB-FT (sans données fictives).
### 4.2 Fiche membre Affichage KYC
- [ ] T022 Étendre le modèle membre (ex. `MembreModel` ou DTO détail) avec `niveauVigilanceKyc`, `statutKyc`, `dateVerificationIdentite` selon lAPI — `lib/features/members/data/models/`
- [ ] T023 Sur la fiche membre (détail membre ou écran équivalent), afficher en lecture seule le statut KYC et la date de vérification didentité — `lib/features/members/presentation/` et/ou `lib/features/profile/`
- [ ] T024 Sassurer que les données KYC proviennent uniquement de lAPI (pas de valeurs en dur)
**Jalon** : Fiche membre affiche les informations KYC conformément à la spec.
---
## Phase 5 : Finition et transversal
- [ ] T025 Mettre à jour `.specify/memory/inventaire-code.md` avec les changements mobile (modèles, écrans, constantes)
- [ ] T026 Vérifier quaucune donnée fictive nest utilisée en production (listes en dur, mocks métier) pour les flux mutuelles et KYC
- [ ] T027 Exécuter les tests backend et mobile ; corriger les régressions
---
## Dépendances et ordre dexécution
- **Phase 1 (API)** : Peut démarrer immédiatement.
- **Phase 2 (Migrations)** : Dépend de la stabilité des champs API (Phase 1).
- **Phase 3 (Impl)** : Dépend des Phases 1 et 2.
- **Phase 4 (Mobile)** : Dépend des contrats API (Phase 1) et de préférence de lendpoint/config de seuil (T017). Les tâches 4.1 et 4.2 peuvent être traitées en parallèle une fois les modèles API disponibles.
- **Phase 5** : Après les Phases 14.
Pour **continuer strictement lordre sur la version mobile** : exécuter dabord T018 → T019 → T020 → T021 (épargne), puis T022 → T023 → T024 (fiche membre), puis T025T027.

View File

@@ -0,0 +1,74 @@
# Admin organisation : gestion des membres et import massif Excel avec quota
## Contexte
- Un **administrateur dorganisation** (ADMIN_ORGANISATION) doit pouvoir **gérer les membres de son organisation** (liste, création unitaire, modification).
- Il doit pouvoir **créer des membres en masse** via un **fichier Excel strictement formaté**.
- Le nombre de créations doit être **plafonné** par le **quota de la souscription** (tranche/forme dabonnement) de lorganisation.
## Règles métier
1. **Droits**
- ADMIN_ORGANISATION : accès limité aux membres des organisations quil gère (liste, détail, création, mise à jour, import).
- ADMIN / SUPER_ADMIN : accès à tous les membres (comportement actuel).
2. **Import massif**
- Format : **Excel (.xlsx)** (et optionnellement CSV) avec colonnes obligatoires strictes (ex. nom, prénom, email, téléphone).
- **organisationId** obligatoire pour un org admin ; les membres créés sont rattachés à cette organisation (création de `MembreOrganisation`).
- **Quota** : avant daccepter limport, vérifier que
`quota_utilise + nombre de nouveaux membres à créer ≤ quota_max`
(ou pas de limite si `quota_max` est null, ex. formule Crystal).
- À chaque membre **nouvellement créé** (pas les mises à jour) : créer le lien `MembreOrganisation` et incrémenter `quota_utilise` de la souscription.
- Si le quota est dépassé en cours dimport : rejeter la requête (ou arrêter et retourner les erreurs selon le choix métier).
3. **Souscription**
- Une organisation (racine) a au plus une souscription active (`souscriptions_organisation`).
- `quota_max` = snapshot de la formule (ex. 50 pour Starter, null pour Crystal).
- `quota_utilise` = nombre de membres comptabilisés pour cette souscription (incrémenté à chaque adhésion validée / membre créé dans lorg).
## Existant (WOU/DRY)
- **Backend**
- `MembreResource` : GET list, GET /recherche, POST create, POST /import, GET /import/modele — existants ; à sécuriser et à scoper pour ADMIN_ORGANISATION.
- `MembreImportExportService.importerMembres` : import Excel/CSV existant ; prend déjà `organisationId` ; **manque** : création de `MembreOrganisation`, vérification et incrément du quota.
- Entités : `SouscriptionOrganisation` (quota_max, quota_utilise, incrementerQuota), `FormuleAbonnement` (max_membres), `MembreOrganisation` (lien membreorganisation).
- **Mobile**
- Annuaire membres : critères de recherche avec `organisationIds` ; pour org admin, passer les IDs de “mes organisations” (déjà possible côté app si lAPI les filtre).
## Implémentation préconisée
### Backend
1. **Sécurité et périmètre**
- Sur `MembreResource` : ajouter `@RolesAllowed` adaptés (ex. MEMBRE, ADMIN, ADMIN_ORGANISATION pour liste/création/import).
- Pour un utilisateur avec rôle ADMIN_ORGANISATION (et sans ADMIN/SUPER_ADMIN) :
- Lister les organisations du membre connecté (ex. `OrganisationService.listerOrganisationsPourUtilisateur(email)`).
- **Liste / recherche** : filtrer les membres par ces `organisationIds` (via `MembreOrganisation`).
- **Création** : exiger un `organisationId` dans le corps (ou le déduire) et vérifier quil appartient à ses organisations ; créer le `MembreOrganisation` après création du membre.
- **Import** : exiger `organisationId` et vérifier quil appartient à ses organisations ; appliquer la règle de quota et créer les `MembreOrganisation` + incrément de quota.
2. **Quota et import**
- **Repository** : `SouscriptionOrganisationRepository` avec `findByOrganisationId(UUID)` (souscription active si besoin).
- **Import** (dans `MembreImportExportService` ou service appelant) :
- Si `organisationId != null` : charger la souscription active de lorganisation.
- Pour chaque ligne du fichier : si cest un **nouveau** membre (création, pas mise à jour) :
- Vérifier `souscription.getPlacesRestantes() > 0` (ou pas de limite si `quota_max == null`).
- Si dépassement : erreur explicite (ex. “Quota souscription atteint (max N membres)”) et arrêt ou rapport derreur.
- Après `creerMembre` : créer `MembreOrganisation` (membre, organisation, statut, dateAdhesion), persister, puis `souscription.incrementerQuota()` et persister la souscription.
3. **Modèle Excel**
- Conserver le modèle actuel (GET `/api/membres/import/modele`) ; documenter les colonnes obligatoires et le fait que le fichier doit être strict (pas de colonnes en plus / types cohérents si besoin).
- Optionnel : endpoint GET pour “quota actuel / places restantes” par organisation (pour affichage côté client).
### Mobile (optionnel dans un second temps)
- Pour un org admin : envoyer en requête liste/recherche les `organisationIds` (ses organisations) pour nafficher que les membres de son périmètre.
- Écran “Import membres” : choix de lorganisation (pré-rempli si une seule), upload du fichier Excel, affichage du quota restant (si lAPI le fournit) et du résultat dimport (succès / erreurs).
## Critères dacceptation
- [ ] Un admin dorganisation ne voit que les membres de ses organisations (liste, recherche).
- [ ] Un admin dorganisation peut créer un membre dans une de ses organisations (et le lien MembreOrganisation est créé).
- [ ] Un admin dorganisation peut lancer un import Excel avec `organisationId` ; le fichier est validé (format strict), le quota souscription est vérifié avant/pendant limport.
- [ ] Les nouveaux membres créés lors de limport sont rattachés à lorganisation et le quota souscription est incrémenté.
- [ ] Si le quota est dépassé (fichier trop gros ou quota déjà saturé), limport est refusé ou sarrête avec un message clair (quota max N, X demandés, etc.).