feat(#131): fiches parent/AM éditable, placement AM↔enfant, statuts garde/sans_garde
Squash merge develop → master. - Fiche parent éditable (co-parent, PATCH fiche, GET /parents) - Fiche AM 3 onglets (PATCH fiche, rattacher/détacher enfants) - Table enfants_assistantes_maternelles + enum garde/sans_garde - Migration SQL + BDD.sql canonique - Correctifs recette : @Get() parents, DTO fiche AM, fix NIR Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+3
-2
@@ -36,6 +36,7 @@ Ce fichier sert d'index pour naviguer dans toute la documentation du projet.
|
||||
- [**23 - Liste des Tickets**](./23_LISTE-TICKETS.md) - 61 tickets Phase 1 détaillés
|
||||
- [**24 - Décisions Projet**](./24_DECISIONS-PROJET.md) - Décisions architecturales et fonctionnelles
|
||||
- [**25 - Backlog Phase 2**](./25_PHASE-2-BACKLOG.md) - Fonctionnalités techniques reportées
|
||||
- [**28 - Évolution famille et responsables**](./28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md) - Modèle dossier/famille, recompositions, v1.0.0 vs post-1.0.0
|
||||
- [**26 - API Gitea**](./26_GITEA-API.md) - Procédure d'utilisation de l'API Gitea (issues, PR, branches, labels)
|
||||
- [**27 - Briefing frontend**](./27_BRIEFING-FRONTEND.md) - Accès Git, priorités, scripts Gitea (token)
|
||||
|
||||
@@ -49,7 +50,7 @@ Fichiers **sans préfixe numérique** encore à la racine par **héritage** ou
|
||||
références outils (`.cursorrules`, etc.) — **à renommer** en `NN_` quand
|
||||
possible :
|
||||
- `CHARTE_GRAPHIQUE.md`
|
||||
- `EVOLUTIONS_CDC.md`
|
||||
- [`EVOLUTIONS_CDC.md`](./EVOLUTIONS_CDC.md) — écarts CDC / app ; voir aussi [**28 - Évolution famille**](./28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md)
|
||||
- `SuperNounou_Cahier_Des_Charges_Complet_V1.1.md`
|
||||
- `SuperNounou_SSS-001.md`
|
||||
|
||||
@@ -89,5 +90,5 @@ PgAdmin: https://app.ptits-pas.fr/pgadmin
|
||||
|
||||
Cette documentation est maintenue par Julien Martin (julien.martin@ptits-pas.fr).
|
||||
|
||||
Dernière mise à jour : Novembre 2025
|
||||
Dernière mise à jour : Juin 2026
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 📋 Décisions Projet - P'titsPas
|
||||
|
||||
**Version** : 1.1
|
||||
**Date** : 9 Février 2026
|
||||
**Version** : 1.2
|
||||
**Date** : 16 Juin 2026
|
||||
**Auteur** : Équipe PtitsPas
|
||||
|
||||
---
|
||||
@@ -122,6 +122,27 @@ ptitspas-app/
|
||||
|
||||
---
|
||||
|
||||
### 5bis. Familles recomposées — contournement v1.0.0
|
||||
|
||||
**Décision** : ✅ **Second compte / second email pour les cas multi-contextes en v1.0.0** ; évolution structurelle reportée post-1.0.0
|
||||
|
||||
**Contexte** :
|
||||
- Le numéro de dossier et le graphe « famille » (co-parent + enfants partagés) conviennent aux cas simples (un couple, N enfants).
|
||||
- Ils ne couvrent pas proprement une même personne responsable dans **plusieurs unités familiales** (recompositions, plusieurs co-responsables successifs, tuteur/GP sur plusieurs contextes).
|
||||
|
||||
**Décision v1.0.0** :
|
||||
- **Contournement opérationnel** : créer un **second compte** avec **email distinct** et un **second numéro de dossier** (souvent via le gestionnaire).
|
||||
- Le numéro de dossier reste la **norme** pour les cas simples, **sans obligation absolue** pour les cas complexes.
|
||||
- Rôle applicatif unique **`parent`** pour tous les responsables (tuteur, GP inclus) ; qualification juridique = évolution ultérieure.
|
||||
|
||||
**Évolution post-1.0.0** :
|
||||
- **Parcours gestionnaire « famille complexe »** (§ 7.5 doc 28) : N responsables, **M un seul compte** avec tous ses enfants ; **A / B** limités à leur enfant via `enfants_parents`.
|
||||
- Visibilité et workflows **sans fusion graphe familial** ; numéro de dossier optionnel ; qualification du lien responsable–enfant.
|
||||
|
||||
**Référence** : [28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md](./28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md) — § 4.4, § 7.5
|
||||
|
||||
---
|
||||
|
||||
### 6. Genre enfant obligatoire (H/F)
|
||||
|
||||
**Décision** : ✅ **Genre obligatoire (H/F uniquement)**
|
||||
@@ -562,6 +583,7 @@ docs/
|
||||
| 14 | Migration données | ❌ Rejeté | N/A |
|
||||
| 15 | Doc utilisateur | ⏸️ Phase 2 | Formation |
|
||||
| 31 | Logs Winston | ✅ Phase 1 | Monitoring |
|
||||
| 5bis | Familles recomposées — 2ᵉ compte v1.0.0 | ✅ v1.0.0 | Métier / dossier |
|
||||
|
||||
---
|
||||
|
||||
@@ -571,10 +593,12 @@ docs/
|
||||
|------|---------|---------------|
|
||||
| 25/11/2025 | 1.0 | Création du document - Toutes les décisions initiales |
|
||||
| 09/02/2026 | 1.1 | Configuration initiale : un seul panneau Paramètres (3 sections) dans le dashboard, plus de Setup Wizard dédié ; navigation bloquée jusqu'à sauvegarde |
|
||||
| 16/06/2026 | 1.2 | Décision 5bis — familles recomposées, contournement v1.0.0 ; lien doc [28](./28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md) |
|
||||
| 16/06/2026 | 1.3 | Précision 5bis — cible post-1.0.0 : parcours gestionnaire § 7.5 (#139), visibilité par enfant |
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour** : 9 Février 2026
|
||||
**Version** : 1.1
|
||||
**Dernière mise à jour** : 16 Juin 2026
|
||||
**Version** : 1.2
|
||||
**Statut** : ✅ Document validé
|
||||
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
# Évolution — Modèle famille, responsables légaux et dossiers
|
||||
|
||||
**Version** : 1.1
|
||||
**Date** : 16 juin 2026
|
||||
**Statut** : Réflexions produit / architecture — complément au [CDC](./01_CAHIER-DES-CHARGES.md)
|
||||
**Documents liés** : [EVOLUTIONS_CDC.md](./EVOLUTIONS_CDC.md), [24_DECISIONS-PROJET.md](./24_DECISIONS-PROJET.md), [23_LISTE-TICKETS.md](./23_LISTE-TICKETS.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Objet de ce document
|
||||
|
||||
Ce document **trace les réflexions** menées en 2026 sur :
|
||||
|
||||
- les **limites du modèle « famille / numéro de dossier »** en v1.0.0 ;
|
||||
- les **contournements** acceptés pour la release **1.0.0** ;
|
||||
- les **évolutions** envisagées post-1.0.0 (unités de dossier, affiliation parent–enfant, terminologie).
|
||||
|
||||
Il ne remplace pas le CDC : il documente l’**écart assumé** entre le modèle idéal long terme et ce qui est livré en **1.0.0**, ainsi que la **feuille de route** pour aller plus loin.
|
||||
|
||||
---
|
||||
|
||||
## 2. Modèle actuel (v1.0.0) — rappel
|
||||
|
||||
| Concept | Implémentation |
|
||||
|--------|----------------|
|
||||
| **Responsable inscrit** | Rôle applicatif `parent` + entité `parents` |
|
||||
| **Second adulte** | Co-parent optionnel (`id_co_parent`) — **un seul** |
|
||||
| **Enfant** | Entité `enfants` |
|
||||
| **Affiliation** | Table `enfants_parents` (liens many-to-many) |
|
||||
| **Dossier famille** | `dossier_famille` + `dossier_famille_enfants` (motivation, etc.) |
|
||||
| **Numéro de dossier** | Format `AAAA-NNNNNN`, sur `utilisateurs` et `parents` |
|
||||
| **« Famille » calculée** | Graphe : co-parent **ou** enfants partagés (`getFamilyUserIds`) |
|
||||
| **Workflows** | Validation, refus, reprise : souvent **par `numero_dossier`** ou par ce graphe |
|
||||
|
||||
Le numéro de dossier est aujourd’hui une **aide forte** pour les cas simples (un couple, N enfants, une motivation), mais il tend à devenir **l’identifiant métier** de la famille — ce qui pose problème dans les cas complexes.
|
||||
|
||||
---
|
||||
|
||||
## 3. Limitation connue v1.0.0 — familles recomposées et multi-contextes
|
||||
|
||||
### 3.1 Exemple type (illustration)
|
||||
|
||||
```
|
||||
Année 1 : Responsable M + co-responsable A → enfant α
|
||||
Année 2 : Responsable M + co-responsable B → enfant β
|
||||
```
|
||||
|
||||
Même personne **M** au centre, **deux contextes de vie** distincts. **A** n’est pas parent de β ; **B** n’est pas parent de α.
|
||||
|
||||
### 3.2 Autres cas couverts par la même limitation
|
||||
|
||||
Les exemples « maman / papa » sont **illustratifs**. La limitation s’applique **à toute configuration** :
|
||||
|
||||
| Configuration | Même règle |
|
||||
|---------------|------------|
|
||||
| Couple **HH** ou **FF** | Oui |
|
||||
| **Père** avec deux partenaires et deux enfants (même ville, écarts d’âge courts) | Oui |
|
||||
| **Grand-parent** en tutelle ou **tuteur légal** | Oui *(voir § 5)* |
|
||||
| Recomposition, demi-fratrie, garde alternée complexe | Oui |
|
||||
|
||||
### 3.3 Pourquoi le modèle casse
|
||||
|
||||
1. **Un `numero_dossier` par user** — M ne peut pas appartenir proprement à deux unités.
|
||||
2. **Un seul co-parent** par fiche `parents`.
|
||||
3. **Graphe famille trop large** — M liée à A (via α) et à B (via β) → A, B et M peuvent être fusionnés en **une seule « famille »** pour validation/refus/reprise.
|
||||
4. **`dossier_famille`** — une motivation / une ancre par numéro, pas deux contextes pour la même personne.
|
||||
|
||||
---
|
||||
|
||||
## 4. Décision v1.0.0 — contournement opérationnel
|
||||
|
||||
### 4.1 Principe
|
||||
|
||||
> **Le numéro de dossier reste la norme pour les cas simples, pas une obligation absolue.**
|
||||
> Pour les cas trop complexes, le **gestionnaire** compose manuellement (création admin, rattachements) ou applique le contournement ci-dessous.
|
||||
|
||||
### 4.2 Contournement accepté pour la 1.0.0
|
||||
|
||||
**Créer un second compte** avec une **adresse e-mail distincte** et un **second dossier** (second `numero_dossier`).
|
||||
|
||||
| Dossier | Compte | Co-responsable | Enfant |
|
||||
|---------|--------|----------------|--------|
|
||||
| 1 | `m.personne@…` | A | α |
|
||||
| 2 | `m.personne.famille2@…` *(ou alias)* | B | β |
|
||||
|
||||
**Conséquences assumées :**
|
||||
|
||||
- Une **même personne physique** peut avoir **deux identités** dans l’app.
|
||||
- Pas de vue unifiée « une personne, deux contextes » en v1.0.0.
|
||||
- Procédure interne gestionnaire recommandée (note « même personne physique »).
|
||||
- Emails distincts **volontaires** (alias, +tag, boîte dédiée selon infra mail).
|
||||
|
||||
### 4.3 Nuance — inscription publique
|
||||
|
||||
Si le **dossier 1** existe déjà avec l’email de P (titulaire ou co-parent), une **2ᵉ inscription publique** où l’on saisit **le même email** comme co-parent est **bloquée** (*email déjà utilisé*).
|
||||
|
||||
Le **2ᵉ dossier** passe donc surtout par :
|
||||
|
||||
- **création / composition par le gestionnaire** (tickets admin #129+), ou
|
||||
- **2ᵉ email** dès le départ pour la même personne physique.
|
||||
|
||||
### 4.4 Piste cible — parcours gestionnaire « famille complexe » *(réflexion juin 2026)*
|
||||
|
||||
Le contournement § 4.2 reste valable en **v1.0.0**. La **solution produit visée** pour les cas complexes est différente :
|
||||
|
||||
> **Seul le gestionnaire** dispose d’un **parcours de création dédié** permettant de constituer une configuration avec **plus de deux responsables** (parents, co-parents, tuteurs…) **sans** se limiter au seul champ `co_parent`, en s’appuyant sur **`enfants_parents`** comme vérité de visibilité.
|
||||
|
||||
**Exemple M / A / B / α / β :**
|
||||
|
||||
| Compte | Enfants visibles / rattachés |
|
||||
|--------|------------------------------|
|
||||
| **M** (un seul compte, un email) | α **et** β |
|
||||
| **A** | α uniquement |
|
||||
| **B** | β uniquement |
|
||||
|
||||
```
|
||||
α ─── M ─── β
|
||||
│ │
|
||||
A B
|
||||
```
|
||||
|
||||
- **M** voit et gère **ses deux enfants** sur **le même compte** (plus besoin d’un 2ᵉ email pour M).
|
||||
- **A** et **B** ne voient **que** l’enfant qui leur est rattaché via `enfants_parents` — pas de fusion « famille » qui mélange A et B.
|
||||
- Le parcours n’est **pas** proposé à l’inscription publique (trop error-prone) : **réservé au gestionnaire** (#129+ ou ticket dédié « famille complexe »).
|
||||
|
||||
**Conséquences techniques (post-1.0.0) :**
|
||||
|
||||
1. **Visibilité** : filtrer listes, fiches et actions parent par **liens `enfants_parents`**, pas par `getFamilyUserIds` / co-parent.
|
||||
2. **Workflows** (validation, refus, reprise) : périmètre par **enfant** ou **soumission**, pas par graphe familial élargi.
|
||||
3. **`co_parent`** : reste utile pour le cas simple (couple + N enfants communs) ; **insuffisant seul** pour les cas complexes — le gestionnaire compose les liens enfant par enfant.
|
||||
4. **Numéro de dossier** : optionnel ou secondaire ; peut rester sur M ou sur une « unité » admin, sans imposer un numéro par co-responsable.
|
||||
|
||||
*Détail : § 7.5.*
|
||||
|
||||
---
|
||||
|
||||
## 5. Terminologie — « parent » aujourd’hui, qualification demain
|
||||
|
||||
### 5.1 v1.0.0
|
||||
|
||||
- Rôle technique : **`parent`** pour tout responsable inscrit (y compris tuteur, grand-parent tutrice, etc.).
|
||||
- UI : « Parent 1 », « co-parent », parfois exemples maman/papa — **pas de statut juridique distinct**.
|
||||
|
||||
### 5.2 Évolution post-1.0.0 (piste)
|
||||
|
||||
Séparer deux niveaux :
|
||||
|
||||
| Niveau | Évolution |
|
||||
|--------|-----------|
|
||||
| **Rôle applicatif** | Conserver `parent` = « responsable du dossier » (auth, API) |
|
||||
| **Qualification métier** | Nouveau champ, ex. `qualite_responsable` / `lien_avec_enfant` |
|
||||
|
||||
**Valeurs possibles (exemples)** : parent biologique ou adoptif, co-parent, tuteur légal, grand-parent exerçant la garde, autre responsable légal.
|
||||
|
||||
**Emplacement recommandé** : sur le **lien** `enfants_parents` (par enfant), pas seulement sur le user global.
|
||||
|
||||
**UI** :
|
||||
|
||||
- Libellés neutres : « Responsable 1 / 2 », « 2ᵉ responsable » ;
|
||||
- **Combobox** pour qualifier le lien (admin + éventuellement inscription).
|
||||
|
||||
---
|
||||
|
||||
## 6. Évolutions UI / fonctionnelles liées (backlog)
|
||||
|
||||
Réflexions dashboard admin / gestionnaire (complément CDC §4.5.2–4.5.3).
|
||||
|
||||
> **Statut implémentation (juin 2026)** : §6.1 et §6.2 **en cours de livraison** (tickets #130–#131, #115–#116, #137–#138). §6.3 reporté post-1.0.0 (#129).
|
||||
|
||||
### 6.1 Fiche parent (#131)
|
||||
|
||||
- Modale **éditable** dès l’ouverture (pas lecture seule + « Modifier » factice).
|
||||
- **Retirer l’ID** UUID ; option : **n° de dossier** en lecture seule.
|
||||
- **Statut** en combobox (règles métier à cadrer vs validation/refus #110).
|
||||
- Bas de modale :
|
||||
- `Nombre d'enfants : N` (lecture seule) ;
|
||||
- **Liste des prénoms/noms** (cadre) — consultation, clic → fiche enfant (#138).
|
||||
|
||||
### 6.2 Affiliation parent ↔ enfant (#115, #116, #138)
|
||||
|
||||
- **Vérité métier** : `enfants_parents`.
|
||||
- **Modifier l’affiliation** ≠ modifier le téléphone : gestion des **liens** (détacher / rattacher), avec garde-fous :
|
||||
- ne pas supprimer l’enfant pour retirer un lien ;
|
||||
- au moins un responsable par enfant ;
|
||||
- prudence sur fusion « famille » et co-parents.
|
||||
- **Création enfant** : prioritaire depuis **fiche parent** (contexte famille) ; onglet **Enfants** (#137) pour vue globale + rattachement.
|
||||
|
||||
### 6.3 Création admin sans numéro (tickets #129+)
|
||||
|
||||
Le gestionnaire doit pouvoir **tout créer** depuis l’interface ; le numéro reste **généré si utile**, **optionnel** si le cas est trop complexe — **objectif post-1.0.0** (unité de dossier).
|
||||
|
||||
---
|
||||
|
||||
## 7. Évolution structurelle post-1.0.0 — « unité de dossier »
|
||||
|
||||
### 7.1 Principe cible
|
||||
|
||||
| Aujourd’hui | Cible |
|
||||
|-------------|--------|
|
||||
| `numero_dossier` = clé de la famille | **Liens parent↔enfant** = vérité |
|
||||
| Famille déduite du graphe | **Unité de dossier** = regroupement **optionnel** |
|
||||
| Un numéro par inscription | Numéro **optionnel** ; plusieurs unités par personne possibles |
|
||||
|
||||
### 7.2 Exemple cible (cas M / A / B) — deux approches
|
||||
|
||||
**Approche A — unités de dossier séparées** *(piste initiale § 7)* :
|
||||
|
||||
```
|
||||
Unité 1 : numero 2026-000021 — M, A, α
|
||||
Unité 2 : sans numéro (ou 2026-000089) — M, B, β
|
||||
```
|
||||
|
||||
M appartient à **deux unités** ; A et B ne partagent pas la même unité. Peut impliquer **deux contextes de connexion** ou une agrégation côté M.
|
||||
|
||||
**Approche B — parcours gestionnaire « famille complexe »** *(préférée, § 4.4)* :
|
||||
|
||||
```
|
||||
Compte M → enfants α, β
|
||||
Compte A → enfant α
|
||||
Compte B → enfant β
|
||||
(liens enfants_parents ; pas de fusion A↔B)
|
||||
```
|
||||
|
||||
- **Un seul compte pour M** avec **les deux enfants**.
|
||||
- **A** et **B** isolés sur **leur** enfant respectif.
|
||||
- Création **uniquement** par le gestionnaire ; inscription publique inchangée (couple + co-parent classique).
|
||||
|
||||
Les deux approches supposent de **cesser de déduire une « famille » unique** pour les workflows lorsque les liens enfant par enfant divergent. L’approche B maximise l’UX du responsable central (M) sans dupliquer son identité.
|
||||
|
||||
### 7.5 Parcours gestionnaire — création « famille complexe »
|
||||
|
||||
#### 7.5.1 Objectif
|
||||
|
||||
Permettre au **gestionnaire** de monter un dossier où :
|
||||
|
||||
- **N responsables** (≥ 2, parents ou tuteurs) sont créés ou rattachés ;
|
||||
- chaque enfant est lié **explicitement** à un ou plusieurs responsables via `enfants_parents` ;
|
||||
- un responsable (ex. **M**) peut être lié à **plusieurs enfants** dont les **autres** responsables (A, B) ne partagent **pas** la garde.
|
||||
|
||||
#### 7.5.2 Règles produit
|
||||
|
||||
| Règle | Détail |
|
||||
|-------|--------|
|
||||
| **Accès** | Parcours **gestionnaire uniquement** (dashboard), pas inscription publique |
|
||||
| **Responsables** | Création ou rattachement de comptes `parent` ; qualification future sur le lien (§ 5) |
|
||||
| **Visibilité** | Chaque responsable ne voit que **ses** enfants (liens `enfants_parents`) |
|
||||
| **Co-parent UI** | Ne pas forcer « Parent 1 + co-parent unique » ; composition libre côté staff |
|
||||
| **Garde-fous** | Au moins un responsable par enfant ; pas de suppression enfant pour retirer un lien |
|
||||
|
||||
#### 7.5.3 Esquisse du parcours UI (gestionnaire)
|
||||
|
||||
1. **Créer ou identifier** le responsable principal (ex. M).
|
||||
2. **Ajouter d’autres responsables** (A, B, tuteur…) — comptes distincts.
|
||||
3. **Créer les enfants** (α, β…) et, pour chaque enfant, **cocher les responsables** rattachés.
|
||||
4. **Motivation / dossier** : texte global ou par enfant (à cadrer).
|
||||
5. **Validation** : par soumission ou par enfant, sans valider « toute la famille » d’un coup si A et B ne doivent pas être fusionnés.
|
||||
|
||||
#### 7.5.4 Impacts techniques majeurs
|
||||
|
||||
| Domaine | Changement |
|
||||
|---------|------------|
|
||||
| **Auth / API parent** | `GET` enfants, dashboard parent : filtre `enfants_parents` pour l’utilisateur courant |
|
||||
| **`getFamilyUserIds`** | Ne plus utiliser pour visibilité parent ; réservé au cas simple ou deprecated progressivement |
|
||||
| **Validation / refus** | Périmètre enfant ou responsable, pas fusion A+B via graphe |
|
||||
| **Reprise (#112)** | Token / périmètre = enfants liés au compte refusé, pas toute la composante connexe |
|
||||
| **Admin (#115–#138)** | Prérequis : rattachement/détachement déjà en place ; ce parcours **compose** ces briques |
|
||||
|
||||
#### 7.5.5 Lien avec v1.0.0
|
||||
|
||||
| Phase | Comportement |
|
||||
|-------|--------------|
|
||||
| **v1.0.0** | Contournement § 4.2 (2ᵉ email M) + composition manuelle gestionnaire (#115–#138) |
|
||||
| **Post-1.0.0** | Parcours § 7.5 + refonte visibilité / workflows |
|
||||
|
||||
### 7.3 Impacts workflows
|
||||
|
||||
| Flux | Adaptation future |
|
||||
|------|-------------------|
|
||||
| Validation / refus (#110) | Par **enfant / soumission**, pas par graphe global |
|
||||
| Reprise (#112) | Périmètre = enfants liés au compte, pas composante connexe |
|
||||
| Liste « à valider » | Par soumission ou par enfant |
|
||||
| Recherche gestionnaire | Numéro **ou** nom **ou** enfant |
|
||||
| Visibilité parent | **Uniquement** enfants via `enfants_parents` (approche B § 7.2) |
|
||||
|
||||
### 7.4 Migration
|
||||
|
||||
- **Court terme** : contournement § 4 + tickets admin.
|
||||
- **Moyen terme** : table **unité de dossier**, `numero_dossier` nullable.
|
||||
- **Long terme** : workflows branchés sur l’unité.
|
||||
- Dossiers **existants** (couple + enfants) : une unité = un numéro → **comportement actuel préservé**.
|
||||
|
||||
---
|
||||
|
||||
## 8. Tickets Gitea associés
|
||||
|
||||
| Ticket | Sujet |
|
||||
|--------|--------|
|
||||
| #110 | Refus dossier (token reprise) — livré |
|
||||
| #112 | Reprise après refus — livré |
|
||||
| #115 / #116 | Rattachement parent — backend / front |
|
||||
| #129+ | Création dossier admin (parent / AM) |
|
||||
| #131 | Fiche parent éditable (dashboard) |
|
||||
| #137 | Onglet Enfants — liste globale |
|
||||
| #138 | Fiche enfant + liste dans fiche parent |
|
||||
| *(à créer)* | Epic « Unité de dossier / numéro optionnel » |
|
||||
| #139 | **Parcours gestionnaire « famille complexe »** (§ 7.5) — N responsables, visibilité par enfant |
|
||||
| *(à créer)* | Qualification responsable légal (combobox sur lien enfant) |
|
||||
|
||||
---
|
||||
|
||||
## 9. Formulation type — release notes / doc gestionnaire (v1.0.0)
|
||||
|
||||
> **Familles recomposées ou responsabilités multiples**
|
||||
> Une même personne ne peut pas gérer proprement deux unités familiales distinctes (recompositions, plusieurs co-responsables successifs, tuteur/GP pour plusieurs contextes) avec **un seul compte**.
|
||||
> **Contournement v1.0.0** : second compte avec **email distinct** et second numéro de dossier.
|
||||
> S’applique à **tous les responsables inscrits** (couples HH/FF, tuteurs, grands-parents, etc.).
|
||||
> **Évolution post-1.0.0** : parcours **gestionnaire** « famille complexe » (un compte M, enfants α+β ; A et B limités à leur enfant) ; visibilité par `enfants_parents` ; workflows sans fusion graphe familial.
|
||||
|
||||
---
|
||||
|
||||
## 10. Historique des mises à jour
|
||||
|
||||
| Date | Auteur | Modification |
|
||||
|------|--------|--------------|
|
||||
| 2026-06-16 | Équipe / session produit | Création — synthèse réflexions famille, tutelle, v1.0.0 vs post-1.0.0 |
|
||||
| 2026-06-16 | Implémentation ch.6 | Back : `PATCH /parents/:id/fiche`, attach/detach enfant. Front : modale parent éditable, onglet Enfants, fiche enfant |
|
||||
| 2026-06-16 | Réflexion produit | § 4.4 / § 7.5 — parcours gestionnaire famille complexe : M un compte (α+β), A/B visibilité restreinte par enfant |
|
||||
|
||||
---
|
||||
|
||||
*Ce document sera enrichi au fil des décisions. Pour les décisions formelles archivées, voir aussi [24_DECISIONS-PROJET.md](./24_DECISIONS-PROJET.md).*
|
||||
+28
-1
@@ -2,6 +2,8 @@
|
||||
|
||||
Ce document liste les modifications à apporter au cahier des charges original pour le rendre conforme à l'application développée.
|
||||
|
||||
> **Document complémentaire (juin 2026)** — réflexions sur le **modèle famille / numéro de dossier**, familles recomposées, tuteurs et responsables légaux : voir **[28 - Évolution famille et responsables](./28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md)**.
|
||||
|
||||
## 1. Gestion des Enfants
|
||||
|
||||
### Modifications à apporter dans la section "Création de compte parent"
|
||||
@@ -275,4 +277,29 @@ Pour chaque évolution identifiée, ce document suivra la structure suivante :
|
||||
- Évolution du modèle de données vers un RBAC intra-RPE.
|
||||
- Adaptation des écrans d'administration pour gérer les rôles locaux.
|
||||
- Renforcement des contrôles d'accès backend et des règles métier.
|
||||
- Clarification des workflows décisionnels dans l'application.
|
||||
- Clarification des workflows décisionnels dans l'application.
|
||||
|
||||
## 9. Modèle famille, numéro de dossier et responsables légaux
|
||||
|
||||
### 9.1 Situation actuelle (v1.0.0)
|
||||
|
||||
- Un **numéro de dossier** par inscription (`AAAA-NNNNNN`), fortement utilisé dans les workflows (validation, refus, reprise).
|
||||
- **Un co-parent** par fiche `parents` ; affiliation réelle via `enfants_parents`.
|
||||
- La « famille » est **déduite** du graphe (co-parent + enfants partagés) — fusion parfois trop large en cas de recompositions.
|
||||
|
||||
### 9.2 Limitation v1.0.0 — familles recomposées
|
||||
|
||||
Cas type : même responsable M avec co-responsable A (enfant α) puis co-responsable B (enfant β). Le modèle actuel ne permet pas de séparer proprement **deux unités familiales** pour une même personne.
|
||||
|
||||
**Contournement accepté pour la release 1.0.0** : second compte avec **email distinct** et second numéro de dossier (procédure gestionnaire). S'applique aussi aux couples HH/FF, tuteurs, grands-parents, etc.
|
||||
|
||||
### 9.3 Évolutions post-1.0.0 (pistes)
|
||||
|
||||
| Sujet | Piste |
|
||||
|-------|--------|
|
||||
| **Unité de dossier** | Numéro **optionnel** ; plusieurs unités par personne |
|
||||
| **Affiliation** | Gestion admin des liens parent↔enfant (#115, #116, #138) |
|
||||
| **Qualification** | Combobox « lien responsable–enfant » (tuteur, GP, parent…) sur `enfants_parents` |
|
||||
| **UI admin** | Fiche parent éditable (#131), liste enfants en bas de fiche |
|
||||
|
||||
**Détail complet, scénarios, tickets et formulation release notes** : [28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md](./28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md).
|
||||
@@ -0,0 +1,127 @@
|
||||
# #131 — En-tête fiche parent : co-parent (note front → back)
|
||||
|
||||
**Ticket :** #131 (fiche parent dashboard, doc `28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md` §6.1)
|
||||
**Date :** 2026-06-01
|
||||
**Statut front :** livré (en-tête dynamique)
|
||||
**Modif backend demandée :** **aucune fonctionnelle** — ce document fixe le contrat attendu ; le back valide `co_parent` et masque les champs sensibles.
|
||||
|
||||
---
|
||||
|
||||
## 1. Comportement UI (front)
|
||||
|
||||
Dans la modale **fiche parent** (`AdminParentEditModal`) :
|
||||
|
||||
| Zone | Contenu |
|
||||
|------|---------|
|
||||
| **Titre** | `prenom` + `nom` du parent affiché (plus le libellé fixe « Fiche parent ») |
|
||||
| **Sous-titre** | `Co-parent : {prenom} {nom}` — affiché **uniquement** si un co-parent est connu |
|
||||
|
||||
Le titre se met à jour en direct pendant l’édition des champs nom/prénom.
|
||||
Le sous-titre provient du co-parent **chargé depuis l’API** (pas saisi à la main dans la modale).
|
||||
|
||||
---
|
||||
|
||||
## 2. Endpoints consommés
|
||||
|
||||
| Méthode | Route | Usage front |
|
||||
|---------|-------|-------------|
|
||||
| `GET` | `/api/v1/parents` | Liste parents (onglet Parents) |
|
||||
| `GET` | `/api/v1/parents/:userId` | Rechargement fiche après rattachement/détachement enfant |
|
||||
| `PATCH` | `/api/v1/parents/:userId/fiche` | Sauvegarde identité + statut (inchangé) |
|
||||
|
||||
Rôles : `super_admin`, `gestionnaire`, `administrateur` (selon route).
|
||||
|
||||
---
|
||||
|
||||
## 3. Contrat JSON attendu pour `co_parent`
|
||||
|
||||
Le front parse `ParentModel.fromJson` avec la clé **`co_parent`** (snake_case), objet utilisateur imbriqué.
|
||||
|
||||
### Champs minimum utilisés pour le sous-titre
|
||||
|
||||
| Clé JSON | Usage |
|
||||
|----------|--------|
|
||||
| `co_parent` | Objet ou absent/`null` |
|
||||
| `co_parent.id` | Identifiant (futur lien cliquable éventuel) |
|
||||
| `co_parent.prenom` | Affichage |
|
||||
| `co_parent.nom` | Affichage |
|
||||
|
||||
Affichage front : `'{prenom} {nom}'.trim()` → libellé `Co-parent : …`.
|
||||
|
||||
### Exemple de fragment de réponse (`GET /parents/:id`)
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "33333333-3333-3333-3333-333333333333",
|
||||
"numero_dossier": "2026-000042",
|
||||
"user": {
|
||||
"id": "33333333-3333-3333-3333-333333333333",
|
||||
"email": "parent1@example.com",
|
||||
"prenom": "Paul",
|
||||
"nom": "PARENT",
|
||||
"statut": "actif",
|
||||
"telephone": "0601020304"
|
||||
},
|
||||
"co_parent": {
|
||||
"id": "44444444-4444-4444-4444-444444444444",
|
||||
"email": "coparent1@example.com",
|
||||
"prenom": "Clara",
|
||||
"nom": "COPARENT",
|
||||
"role": "parent",
|
||||
"statut": "actif"
|
||||
},
|
||||
"parentChildren": []
|
||||
}
|
||||
```
|
||||
|
||||
> **Note :** le front lit `user` (pas `utilisateur`). La doc `11_API.md` § Parents mentionne encore `utilisateur` / `id_co_parent` seul — le contrat **effectif** côté Nest/TypeORM est l’entité `Parents` sérialisée (`user`, `co_parent`, `parentChildren`, …).
|
||||
|
||||
---
|
||||
|
||||
## 4. État backend
|
||||
|
||||
### Relations (déjà en place)
|
||||
|
||||
- `findAll()` et `findOne(user_id)` chargent **`co_parent`** ;
|
||||
- FK : `parents.id_co_parent` → `utilisateurs.id` ;
|
||||
- inscription couple : les deux sens renseignés en principe (`auth.service.ts`).
|
||||
|
||||
### Livraison back (#131)
|
||||
|
||||
- `mapParentForApi` / `sanitizeUserForApi` : réponses `GET/PATCH/POST/DELETE` parents **sans** `password`, `token_creation_mdp`, `password_reset_*` sur `user` et `co_parent`.
|
||||
|
||||
**Checklist validation :**
|
||||
|
||||
- [x] `GET /parents/:id` renvoie `co_parent` peuplé quand `id_co_parent` est non null
|
||||
- [x] `GET /parents` (liste) inclut `co_parent`
|
||||
- [x] `prenom` / `nom` du co-parent présents
|
||||
- [x] Pas de fuite `password` / tokens sur `user` ni `co_parent`
|
||||
|
||||
---
|
||||
|
||||
## 5. Points d’attention (hors périmètre immédiat)
|
||||
|
||||
| Sujet | Détail |
|
||||
|-------|--------|
|
||||
| **Lien inverse** | Si B est co-parent de A (`A.id_co_parent = B`) mais `B.id_co_parent` est `null`, le sous-titre **ne s’affichera pas** sur la fiche de B. Pas de résolution inverse côté front. |
|
||||
| **Familles > 2 adultes** | Sous-titre = co-parent direct (`id_co_parent`) uniquement. |
|
||||
| **Trou AM ↔ enfants en garde** | Pas de lien AM–enfant aujourd’hui (à documenter / traiter plus tard). |
|
||||
|
||||
---
|
||||
|
||||
## 6. Fichiers back concernés
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---------|------|
|
||||
| `backend/src/routes/parents/parents.service.ts` | `findOne`, `findAll` + relations |
|
||||
| `backend/src/routes/parents/parents.controller.ts` | `mapParentForApi` sur les réponses |
|
||||
| `backend/src/routes/parents/parents.mapper.ts` | Sérialisation API |
|
||||
| `backend/src/common/utils/sanitize-user-for-api.ts` | Masquage secrets |
|
||||
| `backend/src/entities/parents.entity.ts` | relation `co_parent` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Références
|
||||
|
||||
- `docs/28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md` §6.1
|
||||
- Ticket Gitea **#131**
|
||||
@@ -0,0 +1,244 @@
|
||||
# #112 — Alignement front après évolution back (reprise dossier complet)
|
||||
|
||||
**Branche déployée :** `feature/112-reprise-apres-refus-front`
|
||||
**Commit back :** `d70577b1` — `feat(#112): reprise après refus — dossier complet GET/PATCH`
|
||||
**Date :** 2026-06-16
|
||||
|
||||
Ce document décrit le **contrat API réel** après extension du back, et ce que le front doit encore brancher pour exploiter le dossier complet (au-delà de l’identité seule).
|
||||
|
||||
---
|
||||
|
||||
## 1. Endpoints (inchangés côté URL)
|
||||
|
||||
| Méthode | Route | Auth |
|
||||
|---------|-------|------|
|
||||
| `GET` | `/api/v1/auth/reprise-dossier?token={uuid}` | Public |
|
||||
| `PATCH` | `/api/v1/auth/reprise-resoumettre` | Public |
|
||||
| `POST` | `/api/v1/auth/reprise-identify` | Public (inchangé) |
|
||||
|
||||
> **Note :** le ticket #111 parlait de `PUT` ; l’implémentation reste en **`PATCH`** (comme avant).
|
||||
|
||||
---
|
||||
|
||||
## 2. `GET /auth/reprise-dossier` — réponse enrichie
|
||||
|
||||
### Champs communs (toujours présents)
|
||||
|
||||
Identiques à avant : `id`, `email`, `prenom`, `nom`, `telephone`, `adresse`, `ville`, `code_postal`, `numero_dossier`, `role`, `photo_url`, `genre`, `situation_familiale`.
|
||||
|
||||
### Rôle `parent` (+ champs #119)
|
||||
|
||||
Alignés sur `DossierFamilleCompletDto` :
|
||||
|
||||
```json
|
||||
{
|
||||
"parents": [
|
||||
{
|
||||
"user_id": "uuid",
|
||||
"email": "…",
|
||||
"prenom": "…",
|
||||
"nom": "…",
|
||||
"telephone": "…",
|
||||
"adresse": "…",
|
||||
"ville": "…",
|
||||
"code_postal": "…",
|
||||
"statut": "refuse",
|
||||
"co_parent_id": "uuid-parent-entity"
|
||||
}
|
||||
],
|
||||
"enfants": [
|
||||
{
|
||||
"id": "uuid-enfant",
|
||||
"first_name": "Emma",
|
||||
"last_name": "MARTIN",
|
||||
"genre": "F",
|
||||
"status": "actif",
|
||||
"birth_date": "2023-02-15T00:00:00.000Z",
|
||||
"due_date": null,
|
||||
"photo_url": "/uploads/photos/…",
|
||||
"consent_photo": true,
|
||||
"est_multiple": false
|
||||
}
|
||||
],
|
||||
"texte_motivation": "Nous recherchons…"
|
||||
}
|
||||
```
|
||||
|
||||
**Mapping front suggéré :**
|
||||
|
||||
| JSON back | Modèle / wizard parent |
|
||||
|-----------|-------------------------|
|
||||
| `parents[]` | `UserRegistrationData.parent1` + `parent2` (matcher par `email` ou ordre : titulaire = `id` du GET racine) |
|
||||
| `enfants[].first_name` / `last_name` | `ChildData.firstName` / `lastName` |
|
||||
| `enfants[].birth_date` | `ChildData.birthDate` (ISO → `DateTime`) |
|
||||
| `enfants[].due_date` | `ChildData.dueDate` (enfant `a_naitre`) |
|
||||
| `enfants[].status` | `actif` = né, `a_naitre` = à naître |
|
||||
| `enfants[].photo_url` | `ApiConfig.absoluteMediaUrl()` + conserver pour reprise sans re-upload |
|
||||
| `enfants[].id` | **Obligatoire** pour le PATCH (update par id) |
|
||||
| `enfants[].est_multiple` | `grossesse_multiple` si utilisé |
|
||||
| `texte_motivation` | étape présentation / motivation |
|
||||
|
||||
Si `numero_dossier` absent : pas de `parents[]` / `enfants[]` / `texte_motivation` (identité seule).
|
||||
|
||||
### Rôle `assistante_maternelle`
|
||||
|
||||
Champs racine + fiche pro (structure **aplatie**, pas de sous-objet `user`) :
|
||||
|
||||
```json
|
||||
{
|
||||
"consentement_photo": true,
|
||||
"date_naissance": "1985-03-12T00:00:00.000Z",
|
||||
"lieu_naissance_ville": "Paris",
|
||||
"lieu_naissance_pays": "France",
|
||||
"numero_agrement": "AGR-2024-12345",
|
||||
"nir": "123456789012345",
|
||||
"date_agrement": "2024-06-01T00:00:00.000Z",
|
||||
"nb_max_enfants": 4,
|
||||
"place_disponible": 2,
|
||||
"biographie": "…"
|
||||
}
|
||||
```
|
||||
|
||||
**Mapping `AmRegistrationData` :**
|
||||
|
||||
| JSON back | Champ front |
|
||||
|-----------|-------------|
|
||||
| `nb_max_enfants` | `capaciteAccueil` |
|
||||
| `place_disponible` | `placesDisponibles` |
|
||||
| `numero_agrement` | `numeroAgrement` |
|
||||
| `biographie` | `biographie` / présentation |
|
||||
| `photo_url` | déjà géré via `RepriseSession.photoUrl` |
|
||||
|
||||
---
|
||||
|
||||
## 3. `PATCH /auth/reprise-resoumettre` — body étendu
|
||||
|
||||
### Commun
|
||||
|
||||
```json
|
||||
{ "token": "uuid-reprise" }
|
||||
```
|
||||
|
||||
### Parent — champs à envoyer depuis le wizard
|
||||
|
||||
| Champ PATCH | Source wizard | Notes |
|
||||
|-------------|---------------|-------|
|
||||
| `prenom`, `nom`, `telephone`, `adresse`, `ville`, `code_postal` | Parent 1 (titulaire token) | Champs racine |
|
||||
| `co_parent_prenom`, `co_parent_nom`, `co_parent_telephone` | Parent 2 | |
|
||||
| `co_parent_meme_adresse`, `co_parent_adresse`, `co_parent_code_postal`, `co_parent_ville` | Parent 2 adresse | |
|
||||
| `texte_motivation` **ou** `presentation_dossier` | Étape motivation | Les deux alias acceptés |
|
||||
| `enfants[]` | Liste enfants | Voir ci-dessous |
|
||||
|
||||
**Structure `enfants[]` (miroir inscription + `id` obligatoire) :**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "uuid-enfant-existant",
|
||||
"prenom": "Emma",
|
||||
"nom": "MARTIN",
|
||||
"date_naissance": "2023-02-15",
|
||||
"date_previsionnelle_naissance": null,
|
||||
"genre": "F",
|
||||
"photo_base64": "data:image/jpeg;base64,…",
|
||||
"photo_filename": "emma.jpg",
|
||||
"grossesse_multiple": false
|
||||
}
|
||||
```
|
||||
|
||||
- **v1 back :** update par `id` uniquement — pas de création/suppression d’enfant.
|
||||
- Si `id` inconnu pour ce dossier → **400** `Enfant inconnu pour ce dossier : {id}`.
|
||||
- Sans nouvelle photo : ne pas envoyer `photo_base64` (l’existant est conservé).
|
||||
|
||||
### AM — champs à envoyer
|
||||
|
||||
| Champ PATCH | Source |
|
||||
|-------------|--------|
|
||||
| Identité + `photo_url` ou `photo_base64` + `photo_filename` | Étapes 1–2 |
|
||||
| `consentement_photo`, `date_naissance`, `lieu_naissance_ville`, `lieu_naissance_pays` | Identité |
|
||||
| `numero_agrement`, `nir`, `date_agrement` | Pro |
|
||||
| `capacite_accueil`, `places_disponibles` | Pro |
|
||||
| `biographie` | Présentation |
|
||||
|
||||
Validation NIR identique à l’inscription si `nir` fourni.
|
||||
|
||||
### Réponse succès (nouveau format)
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Dossier resoumis avec succès. Il est de nouveau en attente de validation.",
|
||||
"statut": "en_attente",
|
||||
"user_id": "uuid",
|
||||
"numero_dossier": "2026-000021"
|
||||
}
|
||||
```
|
||||
|
||||
Code HTTP : **200** (pas de corps `Users` brut comme l’ancien back).
|
||||
|
||||
### Effet métier
|
||||
|
||||
- **Parent :** tous les users `role=parent` avec le même `numero_dossier` passent en `en_attente` ; `token_reprise` invalidé sur **tous** (symétrique refus #110).
|
||||
- **AM :** un seul user.
|
||||
|
||||
### E-mail accusé resoumission (parent)
|
||||
|
||||
Après `PATCH` réussi, un e-mail est envoyé à **chaque parent** du dossier (`sendResoumissionPendingEmail`) :
|
||||
- confirmation de resoumission ;
|
||||
- rappel du **numéro de dossier** ;
|
||||
- mention « en attente de validation ».
|
||||
|
||||
Échec SMTP : logué, **ne bloque pas** la resoumission (même règle que l'inscription initiale).
|
||||
|
||||
---
|
||||
|
||||
## 4. Fichiers front à modifier (checklist)
|
||||
|
||||
### Modèles
|
||||
|
||||
- [ ] `lib/models/reprise_dossier.dart` — parser `parents[]`, `enfants[]`, `texte_motivation`, champs AM
|
||||
- [ ] Réutiliser ou mapper vers `DossierFamilleEnfant` / structures existantes (#119 admin) si possible
|
||||
|
||||
### Session / préremplissage
|
||||
|
||||
- [ ] `lib/services/reprise_session.dart`
|
||||
- `applyToParent` : remplir parent1/parent2 depuis `parents[]`, enfants, motivation
|
||||
- `applyToAm` : remplir tous les champs AM
|
||||
|
||||
### API
|
||||
|
||||
- [ ] `lib/services/auth_service.dart` — `resoumettreReprise()` : accepter body complet (parent + AM), pas seulement identité
|
||||
- [ ] Étendre `UserRegistrationData` / `AmRegistrationData` helpers `toReprisePatchBody()` si utile
|
||||
|
||||
### Écrans fin de parcours
|
||||
|
||||
- [ ] `parent_register_step5_screen.dart` — PATCH avec co-parent, enfants, motivation
|
||||
- [ ] `am_register_step4_screen.dart` — PATCH avec fiche AM complète
|
||||
|
||||
### Hors scope back (inchangé)
|
||||
|
||||
RIB / IBAN / attestation CAF (étape 5 wizard parent) : **non persistés** — rien à envoyer en reprise.
|
||||
|
||||
### Non implémenté front (ticket #112 initial)
|
||||
|
||||
- [ ] Modale login « J’ai un numéro de dossier » → `POST /auth/reprise-identify` (back prêt, front absent)
|
||||
|
||||
---
|
||||
|
||||
## 5. Tests manuels suggérés
|
||||
|
||||
1. Refuser un dossier parent complet (≥1 enfant + co-parent + motivation).
|
||||
2. Ouvrir le lien mail `/reprise?token=…`.
|
||||
3. Vérifier dans DevTools que le GET contient `enfants[]` et `texte_motivation`.
|
||||
4. Après branchement front : wizard prérempli sur toutes les étapes.
|
||||
5. Resoumettre → statut `en_attente` pour les deux parents ; dossier visible file validation admin (#119).
|
||||
|
||||
---
|
||||
|
||||
## 6. Références code back
|
||||
|
||||
```
|
||||
backend/src/routes/auth/dto/reprise-dossier.dto.ts
|
||||
backend/src/routes/auth/dto/resoumettre-reprise.dto.ts
|
||||
backend/src/routes/auth/dto/enfant-reprise.dto.ts
|
||||
backend/src/routes/auth/auth.service.ts → getRepriseDossier, resoumettreReprise
|
||||
backend/src/routes/parents/dto/dossier-famille-complet.dto.ts
|
||||
```
|
||||
@@ -0,0 +1,132 @@
|
||||
# #131 — Fiche AM éditable + affiliation enfants (note front → back)
|
||||
|
||||
**Ticket :** #131 (partie AM, doc `28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md` §6.1)
|
||||
**Date :** 2026-06-01
|
||||
**Statut front :** modale livrée (2 onglets) — **API affiliation AM↔enfant à implémenter**
|
||||
|
||||
---
|
||||
|
||||
## 1. Comportement UI (front)
|
||||
|
||||
Modale `AdminAmEditModal` — même shell que la fiche parent (~930 px) :
|
||||
|
||||
| Onglet | Contenu |
|
||||
|--------|---------|
|
||||
| **Identité & professionnel** | `IdentityBlock` éditable + grille pro (agrément, ville résidence, capacité, places, NIR/agrément date en lecture seule, biographie, switch disponible) + gélule statut |
|
||||
| **Enfants accueillis** | Liste cartes enfants (réutilise `AdminChildrenAffiliationPanel` / `AdminEnfantUserCard`) + rattacher / détacher |
|
||||
|
||||
En-tête : prénom nom · sous-titre `Zone · Agrément · Dossier`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Endpoints consommés
|
||||
|
||||
### Déjà existants (partiels)
|
||||
|
||||
| Méthode | Route | Usage |
|
||||
|---------|-------|-------|
|
||||
| `GET` | `/api/v1/assistantes-maternelles` | Liste AM |
|
||||
| `GET` | `/api/v1/assistantes-maternelles/:userId` | Détail (403 possible pour `administrateur` → fallback liste) |
|
||||
| `PATCH` | `/api/v1/users/:userId` | Identité + statut (admin / super_admin uniquement) |
|
||||
| `PATCH` | `/api/v1/assistantes-maternelles/:userId` | Champs pro (gestionnaire / super_admin) |
|
||||
|
||||
### À créer (recommandé — miroir parent #131 / #115)
|
||||
|
||||
| Méthode | Route | Rôle |
|
||||
|---------|-------|------|
|
||||
| `PATCH` | `/api/v1/assistantes-maternelles/:userId/fiche` | Mise à jour unifiée identité + pro + statut (`super_admin`, `gestionnaire`, `administrateur`) |
|
||||
| `POST` | `/api/v1/assistantes-maternelles/:userId/enfants/:enfantId` | Rattacher un enfant |
|
||||
| `DELETE` | `/api/v1/assistantes-maternelles/:userId/enfants/:enfantId` | Détacher un enfant |
|
||||
| `GET` | `/api/v1/assistantes-maternelles/:userId` | Inclure `amChildren[]` (relation enfant) |
|
||||
|
||||
Le front appelle déjà ces routes ; en l’absence de `PATCH …/fiche`, il tente un fallback `PATCH users` + `PATCH assistantes-maternelles` (échoue selon le rôle connecté).
|
||||
|
||||
---
|
||||
|
||||
## 3. Modèle de données affiliation AM ↔ enfant
|
||||
|
||||
**À définir côté BDD** (pas de table dédiée aujourd’hui, contrairement à `enfants_parents`) :
|
||||
|
||||
Proposition alignée parent :
|
||||
|
||||
```sql
|
||||
-- Piste : enfants_assistantes_maternelles
|
||||
CREATE TABLE enfants_assistantes_maternelles (
|
||||
id_am UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
|
||||
id_enfant UUID NOT NULL REFERENCES enfants(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (id_am, id_enfant)
|
||||
);
|
||||
```
|
||||
|
||||
Réponse API attendue sur `GET /assistantes-maternelles/:id` :
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "uuid-am",
|
||||
"user": { "id": "…", "prenom": "Claire", "nom": "MARTIN", "statut": "actif" },
|
||||
"approval_number": "AGR-2024-12345",
|
||||
"residence_city": "Bezons",
|
||||
"max_children": 4,
|
||||
"places_available": 2,
|
||||
"available": true,
|
||||
"amChildren": [
|
||||
{
|
||||
"child": {
|
||||
"id": "uuid-enfant",
|
||||
"first_name": "Emma",
|
||||
"last_name": "MARTIN",
|
||||
"status": "actif",
|
||||
"birth_date": "2023-02-15"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Le front parse `amChildren` / `am_children` / `assistanteChildren` (même logique que `parentChildren`).
|
||||
|
||||
---
|
||||
|
||||
## 4. Body `PATCH …/fiche` suggéré
|
||||
|
||||
```json
|
||||
{
|
||||
"nom": "MARTIN",
|
||||
"prenom": "Claire",
|
||||
"email": "claire@example.com",
|
||||
"telephone": "0612345678",
|
||||
"adresse": "5 place Bellecour",
|
||||
"ville": "Lyon",
|
||||
"code_postal": "69002",
|
||||
"statut": "actif",
|
||||
"approval_number": "AGR-2024-12345",
|
||||
"residence_city": "Lyon",
|
||||
"max_children": 4,
|
||||
"places_available": 2,
|
||||
"biography": "…",
|
||||
"available": true
|
||||
}
|
||||
```
|
||||
|
||||
NIR et date d’agrément : lecture seule dans la modale (modification hors périmètre admin v1).
|
||||
|
||||
---
|
||||
|
||||
## 5. Fichiers front concernés
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---------|------|
|
||||
| `frontend/lib/widgets/admin/common/admin_am_edit_modal.dart` | Modale 2 onglets |
|
||||
| `frontend/lib/widgets/admin/common/admin_children_affiliation_panel.dart` | Liste enfants partagée parent/AM |
|
||||
| `frontend/lib/widgets/admin/common/admin_status_capsule.dart` | Gélule statut partagée |
|
||||
| `frontend/lib/models/assistante_maternelle_model.dart` | Parse champs pro + `amChildren` |
|
||||
| `frontend/lib/services/user_service.dart` | `getAssistanteMaternelle`, `updateAmFiche`, `attachEnfantToAm`, `detachEnfantFromAm` |
|
||||
| `frontend/lib/widgets/admin/assistante_maternelle_management_widget.dart` | Ouverture modale au clic Modifier |
|
||||
|
||||
---
|
||||
|
||||
## 6. Références
|
||||
|
||||
- Fiche parent : `PATCH /parents/:id/fiche`, `POST|DELETE /parents/:id/enfants/:enfantId`
|
||||
- Ticket Gitea **#131**, **#115**
|
||||
- `docs/archive/temporaires/TEMP_131-back-fiche-parent-co-parent.md`
|
||||
@@ -0,0 +1,124 @@
|
||||
# #131 — En-tête fiche parent : co-parent (note front → back)
|
||||
|
||||
**Ticket :** #131 (fiche parent dashboard, doc `28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md` §6.1)
|
||||
**Date :** 2026-06-01
|
||||
**Statut front :** livré (en-tête dynamique)
|
||||
**Modif backend demandée :** **aucune** — ce document fixe le contrat attendu et invite à valider que l’existant le couvre.
|
||||
|
||||
---
|
||||
|
||||
## 1. Comportement UI (front)
|
||||
|
||||
Dans la modale **fiche parent** (`AdminParentEditModal`) :
|
||||
|
||||
| Zone | Contenu |
|
||||
|------|---------|
|
||||
| **Titre** | `prenom` + `nom` du parent affiché (plus le libellé fixe « Fiche parent ») |
|
||||
| **Sous-titre** | `Co-parent : {prenom} {nom}` — affiché **uniquement** si un co-parent est connu |
|
||||
|
||||
Le titre se met à jour en direct pendant l’édition des champs nom/prénom.
|
||||
Le sous-titre provient du co-parent **chargé depuis l’API** (pas saisi à la main dans la modale).
|
||||
|
||||
---
|
||||
|
||||
## 2. Endpoints consommés
|
||||
|
||||
| Méthode | Route | Usage front |
|
||||
|---------|-------|-------------|
|
||||
| `GET` | `/api/v1/parents` | Liste parents (onglet Parents) |
|
||||
| `GET` | `/api/v1/parents/:userId` | Rechargement fiche après rattachement/détachement enfant |
|
||||
| `PATCH` | `/api/v1/parents/:userId/fiche` | Sauvegarde identité + statut (inchangé) |
|
||||
|
||||
Rôles : `super_admin`, `gestionnaire`, `administrateur` (selon route).
|
||||
|
||||
---
|
||||
|
||||
## 3. Contrat JSON attendu pour `co_parent`
|
||||
|
||||
Le front parse `ParentModel.fromJson` avec la clé **`co_parent`** (snake_case), objet utilisateur imbriqué.
|
||||
|
||||
### Champs minimum utilisés pour le sous-titre
|
||||
|
||||
| Clé JSON | Usage |
|
||||
|----------|--------|
|
||||
| `co_parent` | Objet ou absent/`null` |
|
||||
| `co_parent.id` | Identifiant (futur lien cliquable éventuel) |
|
||||
| `co_parent.prenom` | Affichage |
|
||||
| `co_parent.nom` | Affichage |
|
||||
|
||||
Affichage front : `'{prenom} {nom}'.trim()` → libellé `Co-parent : …`.
|
||||
|
||||
### Exemple de fragment de réponse (`GET /parents/:id`)
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "33333333-3333-3333-3333-333333333333",
|
||||
"numero_dossier": "2026-000042",
|
||||
"user": {
|
||||
"id": "33333333-3333-3333-3333-333333333333",
|
||||
"email": "parent1@example.com",
|
||||
"prenom": "Paul",
|
||||
"nom": "PARENT",
|
||||
"statut": "actif",
|
||||
"telephone": "0601020304"
|
||||
},
|
||||
"co_parent": {
|
||||
"id": "44444444-4444-4444-4444-444444444444",
|
||||
"email": "coparent1@example.com",
|
||||
"prenom": "Clara",
|
||||
"nom": "COPARENT",
|
||||
"role": "parent",
|
||||
"statut": "actif"
|
||||
},
|
||||
"parentChildren": []
|
||||
}
|
||||
```
|
||||
|
||||
> **Note :** le front lit `user` (pas `utilisateur`). La doc `11_API.md` § Parents mentionne encore `utilisateur` / `id_co_parent` seul — le contrat **effectif** côté Nest/TypeORM est l’entité `Parents` sérialisée (`user`, `co_parent`, `parentChildren`, …).
|
||||
|
||||
---
|
||||
|
||||
## 4. État backend (à valider, pas à refaire)
|
||||
|
||||
D’après le code actuel (`parents.service.ts`) :
|
||||
|
||||
- `findAll()` et `findOne(user_id)` chargent déjà la relation **`co_parent`** ;
|
||||
- la FK métier est `parents.id_co_parent` → `utilisateurs.id` ;
|
||||
- à l’inscription couple, les deux sens sont en principe renseignés (`auth.service.ts`).
|
||||
|
||||
**Checklist validation back :**
|
||||
|
||||
- [ ] `GET /parents/:id` renvoie bien `co_parent` peuplé quand `id_co_parent` est non null
|
||||
- [ ] `GET /parents` (liste) inclut aussi `co_parent` (sous-titre disponible dès l’ouverture sans re-fetch)
|
||||
- [ ] Les champs `prenom` / `nom` du co-parent sont présents dans la réponse JSON
|
||||
|
||||
Si ces trois points passent en recette, **aucun changement backend n’est nécessaire** pour cette fonctionnalité.
|
||||
|
||||
---
|
||||
|
||||
## 5. Points d’attention (hors périmètre immédiat)
|
||||
|
||||
| Sujet | Détail |
|
||||
|-------|--------|
|
||||
| **Lien inverse** | Si le parent B est le co-parent de A (`A.id_co_parent = B`) mais que `B.id_co_parent` est `null`, le sous-titre **ne s’affichera pas** sur la fiche de B. Le front ne fait pas de résolution inverse. À traiter côté back **seulement si** des données legacy ont un lien à sens unique. |
|
||||
| **Familles > 2 adultes** | Le sous-titre n’affiche que le co-parent direct (`id_co_parent`). Les autres responsables liés uniquement via `enfants_parents` ne sont pas listés ici (cf. doc 28 §6). |
|
||||
| **Données sensibles** | Vérifier que la sérialisation de `co_parent` n’expose pas `password` / tokens (même remarque que pour `user`). |
|
||||
|
||||
---
|
||||
|
||||
## 6. Fichiers front concernés
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---------|------|
|
||||
| `frontend/lib/models/parent_model.dart` | Parse `co_parent` → `AppUser? coParent` |
|
||||
| `frontend/lib/widgets/admin/common/admin_parent_edit_modal.dart` | Titre + sous-titre |
|
||||
| `frontend/lib/services/user_service.dart` | `getParents()` / `getParent()` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Références
|
||||
|
||||
- `docs/28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md` §6.1
|
||||
- `backend/src/routes/parents/parents.service.ts` — `findOne`, `findAll`
|
||||
- `backend/src/entities/parents.entity.ts` — relation `co_parent`
|
||||
- Ticket Gitea **#131**
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user