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