petitspas/docs/archive/temporaires/TEMP_112-back-reprise-alignement-front.md
Julien Martin 003fe6b762 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>
2026-07-11 22:49:57 +02:00

245 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# #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 lidentité 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` ; limplé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 denfant.
- Si `id` inconnu pour ce dossier → **400** `Enfant inconnu pour ce dossier : {id}`.
- Sans nouvelle photo : ne pas envoyer `photo_base64` (lexistant est conservé).
### AM — champs à envoyer
| Champ PATCH | Source |
|-------------|--------|
| Identité + `photo_url` ou `photo_base64` + `photo_filename` | Étapes 12 |
| `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 à linscription 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 lancien 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 « Jai 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
```