Matrice PO #154 : supprimer dossiers famille/AM, parents, enfants et comptes staff avec règles métier (placements clôturés, sans_enfant, cascade foyer, droits gestionnaire/admin). Poubelle en liste, dialogues de confirmation, garde-fou gestionnaire→gestionnaire. Inclut polish hauteur modale fiche AM.
170 lines
4.9 KiB
Markdown
170 lines
4.9 KiB
Markdown
# Mini-spec front — Suppressions dashboard
|
||
|
||
**Ticket front** : **#160** — https://git.ptits-pas.fr/jmartin/petitspas/issues/160
|
||
**Ticket back** : **#159** — https://git.ptits-pas.fr/jmartin/petitspas/issues/159
|
||
**Epic** : #154 (complète #133)
|
||
**Branche back** : `feature/159-suppressions-backend`
|
||
**Doc matrice** : [154-matrice-suppression.md](./154-matrice-suppression.md)
|
||
|
||
Travail **en parallèle** : ce contrat est la source de vérité UI ↔ API.
|
||
|
||
---
|
||
|
||
## UX commune
|
||
|
||
Sur chaque ligne / carte des listes :
|
||
|
||
- Icône **poubelle** en bout de ligne
|
||
- Clic → **dialog de confirmation** (texte d’impact) → DELETE → **refresh** liste
|
||
- Pending = **mêmes** règles que validés
|
||
- **Pas** d’email
|
||
|
||
| Liste | Poubelle visible si |
|
||
|-------|---------------------|
|
||
| Dossiers, Parents, Enfants, AM | gestionnaire **ou** admin |
|
||
| Gestionnaires | **admin** only |
|
||
| Administrateurs | admin+ ; **pas** sur sa propre ligne ; dernier admin : UI warning + réservé super_admin |
|
||
|
||
---
|
||
|
||
## Contrat API
|
||
|
||
Base : auth Bearer. Erreurs : `400` / `403` / `404` / `409` avec `message` FR.
|
||
|
||
### 1. `DELETE /dossiers/:numeroDossier`
|
||
|
||
- **Famille** → supprime tous parents + enfants du n° ; clos placements AM des enfants.
|
||
- **AM** → compte AM + dossier AM ; enfants gardés ; placements clos.
|
||
|
||
**Réponse 200** (exemple) :
|
||
|
||
```json
|
||
{
|
||
"type": "famille",
|
||
"numero_dossier": "2026-000043",
|
||
"deleted_user_ids": ["…"],
|
||
"deleted_enfant_ids": ["…"],
|
||
"message": "Dossier famille supprimé."
|
||
}
|
||
```
|
||
|
||
ou
|
||
|
||
```json
|
||
{
|
||
"type": "assistante_maternelle",
|
||
"numero_dossier": "2026-000015",
|
||
"deleted_user_ids": ["…"],
|
||
"deleted_enfant_ids": [],
|
||
"message": "Dossier assistante maternelle supprimé."
|
||
}
|
||
```
|
||
|
||
**Dialog UI** : lister libellé + n° + « X parent(s), Y enfant(s) » (ou « compte AM, enfants conservés »).
|
||
|
||
---
|
||
|
||
### 2. `DELETE /users/:id`
|
||
|
||
Comportement selon le **rôle** de la cible :
|
||
|
||
| Cible | Effet |
|
||
|-------|--------|
|
||
| Parent **co-parent** | Delete ce user seul |
|
||
| Parent **dernier** du dossier | Delete user + enfants du foyer |
|
||
| AM | Delete user AM + dossier AM ; enfants conservés ; placements clos |
|
||
| Gestionnaire | Admin only ; self → 403 |
|
||
| Administrateur | Self → 403 ; dernier admin → super_admin only sinon 403 ; super_admin → 403 |
|
||
|
||
**Réponse 200** :
|
||
|
||
```json
|
||
{
|
||
"deleted_user_ids": ["…"],
|
||
"deleted_enfant_ids": ["…"],
|
||
"message": "…"
|
||
}
|
||
```
|
||
|
||
**Dialogs** :
|
||
|
||
- Co-parent : « Ce parent sera retiré / supprimé du dossier {n°}. Les enfants restent avec le co-parent. »
|
||
- Dernier parent : « Dernier parent du dossier {n°}. Les enfants rattachés seront aussi supprimés. »
|
||
- AM : « Le compte et le dossier AM seront supprimés. Les enfants accueillis ne seront pas supprimés. »
|
||
|
||
Optionnel (si exposé) : `GET /users/:id/suppression-impact` — sinon calculer depuis données déjà en liste / détail dossier.
|
||
|
||
---
|
||
|
||
### 3. `DELETE /enfants/:id?deleteDossier=true|false`
|
||
|
||
- Pas dernier enfant → delete enfant (`deleteDossier` ignoré ou false).
|
||
- Dernier enfant + `deleteDossier=false` → delete enfant ; dossier famille peut passer `sans_enfant`.
|
||
- Dernier enfant + `deleteDossier=true` → cascade dossier famille (parents + enfants).
|
||
|
||
**Réponse 200** :
|
||
|
||
```json
|
||
{
|
||
"deleted_enfant_ids": ["…"],
|
||
"deleted_user_ids": ["…"],
|
||
"dossier_supprime": false,
|
||
"message": "…"
|
||
}
|
||
```
|
||
|
||
**Dialog** :
|
||
|
||
- Standard : « L’enfant sera supprimé du dossier de {famille} ({n°}). »
|
||
- Dernier : proposer **deux actions** :
|
||
1. Supprimer l’enfant seulement (`deleteDossier=false`)
|
||
2. Supprimer aussi le dossier / parents (`deleteDossier=true`)
|
||
|
||
Pour savoir si dernier : compter enfants du `numero_dossier` (détail dossier ou champ impact API).
|
||
|
||
---
|
||
|
||
### 4. `GET /dossiers` — flag `sans_enfant`
|
||
|
||
Chaque item famille peut exposer :
|
||
|
||
```json
|
||
"sans_enfant": true
|
||
```
|
||
|
||
- `true` si dossier **famille** sans enfant lié.
|
||
- AM : `false` ou omis.
|
||
|
||
**UI** : badge / warning vigilance (comme `sans_responsable` / alertes AM).
|
||
|
||
---
|
||
|
||
## UserService (Flutter) — signatures cibles
|
||
|
||
```dart
|
||
Future<void> deleteDossier(String numeroDossier);
|
||
Future<Map<String, dynamic>> deleteUser(String userId);
|
||
Future<Map<String, dynamic>> deleteEnfant(String enfantId, {bool deleteDossier = false});
|
||
```
|
||
|
||
(Adapter le parsing au JSON réel une fois le back mergé ; en parallèle, stubber sur ce contrat.)
|
||
|
||
---
|
||
|
||
## Fichiers front probables
|
||
|
||
- Cartes listes : `admin_user_card.dart`, `admin_enfant_user_card.dart`, cartes dossiers
|
||
- Listes : `dossiers_management_widget.dart`, `parent_managmant_widget.dart`, `enfant_management_widget.dart`, `assistante_maternelle_management_widget.dart`, `gestionnaire_management_widget.dart`, `admin_management_widget.dart`
|
||
- `user_service.dart`
|
||
|
||
---
|
||
|
||
## Critères front (#160)
|
||
|
||
- [ ] Poubelle selon droits
|
||
- [ ] Confirmations avec impact
|
||
- [ ] Refresh après succès
|
||
- [ ] Dernier enfant : choix dossier oui/non
|
||
- [ ] Warning `sans_enfant`
|
||
- [ ] Self-admin / dernier admin gérés côté UI (masquer ou message 403)
|