# #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 ```