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:
74
unionflow/specs/admin-org-membres-import-quota.md
Normal file
74
unionflow/specs/admin-org-membres-import-quota.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Admin organisation : gestion des membres et import massif Excel avec quota
|
||||
|
||||
## Contexte
|
||||
|
||||
- Un **administrateur d’organisation** (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 d’abonnement) de l’organisation.
|
||||
|
||||
## Règles métier
|
||||
|
||||
1. **Droits**
|
||||
- ADMIN_ORGANISATION : accès limité aux membres des organisations qu’il 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 d’accepter l’import, 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 d’import : 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 l’org).
|
||||
|
||||
## 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 membre–organisation).
|
||||
- **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 l’API 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 qu’il appartient à ses organisations ; créer le `MembreOrganisation` après création du membre.
|
||||
- **Import** : exiger `organisationId` et vérifier qu’il 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 l’organisation.
|
||||
- Pour chaque ligne du fichier : si c’est 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 d’erreur.
|
||||
- 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 n’afficher que les membres de son périmètre.
|
||||
- Écran “Import membres” : choix de l’organisation (pré-rempli si une seule), upload du fichier Excel, affichage du quota restant (si l’API le fournit) et du résultat d’import (succès / erreurs).
|
||||
|
||||
## Critères d’acceptation
|
||||
|
||||
- [ ] Un admin d’organisation ne voit que les membres de ses organisations (liste, recherche).
|
||||
- [ ] Un admin d’organisation peut créer un membre dans une de ses organisations (et le lien MembreOrganisation est créé).
|
||||
- [ ] Un admin d’organisation peut lancer un import Excel avec `organisationId` ; le fichier est validé (format strict), le quota souscription est vérifié avant/pendant l’import.
|
||||
- [ ] Les nouveaux membres créés lors de l’import sont rattachés à l’organisation et le quota souscription est incrémenté.
|
||||
- [ ] Si le quota est dépassé (fichier trop gros ou quota déjà saturé), l’import est refusé ou s’arrête avec un message clair (quota max N, X demandés, etc.).
|
||||
Reference in New Issue
Block a user