# Prompt d'implémentation — M5 · ERP-187 (1.7) — Tests PHPUnit RG-5.01→5.10 + capture contrat JSON Projet **Starseed**. Tâche **back / tests**. Lis `CLAUDE.md`, `.claude/rules/testing.md` et la spec : `docs/specs/M5-tickets-pesee/spec-back.md` (§ 8, § 4.0.bis). Prérequis : ERP-183 → ERP-186 mergés. ## Mission Couvrir les RG du M5 par des tests PHPUnit et **capturer la réponse JSON réelle** (DoD) à coller dans la spec avant le démarrage front. ## Étapes 1. **`WeighingTicketSerializationContractTest`** : seeder un ticket complet (contrepartie Client, pesée vide + plein), capturer le JSON **liste** + **détail** (via une variable d'env de dump, cf. pattern M4 `CARRIER_DOD_DUMP`). Vérifier les **4 pièges** : - `client` / `supplier` sortent en **objet embarqué**, pas en IRI nu ; - `plateFreeFormat` présent dans le JSON ; - `number` présent et formaté `{siteCode}-TP-{NNNN}` ; - `netWeight` = `full - empty` (plein − vide). → **Coller le JSON capturé dans `spec-back.md § 4.0.bis`** (feu vert front). 2. `WeighingTicketNumberingTest` : numéro par site, unicité, concurrence (`FOR UPDATE`), immuabilité au PATCH. 3. `DsdAllocatorTest` : AUTO incrémente / MANUAL = dernier+1 / compteur par site. 4. `WeighbridgeReaderStubTest` : poids ∈ [10000,50000] ; `WeighbridgeUnavailableException` → 503 (RG-5.06). 5. `NetWeightTest` : plein − vide ; `null` si une pesée manque (RG-5.05). 6. `CounterpartyValidationTest` : RG-5.03 (chaque branche valide + rejets des incohérences). 7. `ImmatriculationNormalizationTest` : masque `XX-000-XX`, `plateFreeFormat`, 422 si invalide (RG-5.01). 8. **RBAC** : Admin/Bureau/Usine OK ; Compta/Commerciale → 403 ; anonyme → 401. ## Garde-fous - `declare(strict_types=1);` ; fixtures dédiées sous `tests/Fixtures/`. - **Pas de test E2E** (règle d'or) — PHPUnit uniquement. - Ne pas casser les tests Architecture existants. ## Vérification - `make test` **vert** (suite complète, dont Architecture). - `spec-back.md § 4.0.bis` contient le JSON RÉEL avec les 4 pièges marqués verts. - `make php-cs-fixer-allow-risky`.