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,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.).