diff --git a/docs/tmp/112-back-reprise-alignement-front.md b/docs/tmp/112-back-reprise-alignement-front.md new file mode 100644 index 0000000..d15350b --- /dev/null +++ b/docs/tmp/112-back-reprise-alignement-front.md @@ -0,0 +1,235 @@ +# #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. + +--- + +## 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 +```