feat(transport) : sous-ressource adresses transporteur (ERP-159) #115
Reference in New Issue
Block a user
Delete Branch "feat/erp-159-carrier-addresses"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
POST/PATCH/DELETE carrier_address + RG-4.05→4.07. Ticket ERP-159.
Code review ERP-159 (sous-ressource Adresses transporteur) — relue contre spec-back § 4.5 (RG-4.05/4.06/4.07).
Verdict : PR propre, aucun constat bloquant. Jumelle fidèle de
SupplierAddress(M2) /ProviderAddress(M3) :/carriers/{carrierId}/addresses(Link toProperty+read:falsepour éviter leNonUniqueResult— RETEX M1), PATCH/DELETE sur/carrier_addresses/{id}, securitytransport.carriers.manage(Get enview).^[0-9]{4,5}$(Assert\Regex), whitelistEXCLUDED_LENGTH_MIRRORjustifiée. Messages FR sur toutes les contraintes.CarrierAddressProcessor— correctement, car le parent n'est pas disponible à la validation Symfony sur un POSTread:false; violation par champ viaValidationException(rendu Hydra inline, ERP-101).Tests : RG-4.06, RG-4.05 (incomplet/complet), PATCH/DELETE manage, 403 sans manage. Quelques 🟡 mineurs en inline (assertion propertyPath, 404 parent non testé). Rien qui bloque.
@@ -23,0 +66,4 @@// resoudrait l'enfant (SELECT CarrierAddress ... WHERE carrier = :id)// et casse en NonUniqueResult des >= 2 enfants. Le parent est rattache// manuellement par CarrierAddressProcessor::linkParent (404 si absent).read: false,🟢 Bon pattern (RETEX M1 #110/#542) :
read: false+ rattachement manuel du parent dans le processor évite leNonUniqueResultqu'unLink toPropertyprovoquerait sur un POST sous-ressource dès ≥2 enfants (le Link ferait un SELECT enfant WHERE carrier=:id). Le 404 parent introuvable est géré explicitement dansCarrierAddressProcessor::linkParent. Securitymanagesur l'écriture,viewsur le Get. Conforme § 4.5.@@ -0,0 +91,4 @@// read:false sur le POST : sans stade lecture, un parent introuvable n'est// plus intercepte en amont -> 404 explicite (sinon 500 au persist sur la// contrainte carrier_id NOT NULL).if (!$carrier instanceof Carrier) {🟡 Trou de test (mineur). Ce 404 « Transporteur introuvable » est une logique explicite et non triviale (conséquence directe du
read:false, sinon 500 au persist surcarrier_id NOT NULL). Aucun test ne l'exerce — un POST sur/api/carriers/999999/addressesdevrait renvoyer 404. À ajouter pour figer ce comportement.@@ -0,0 +106,4 @@* payload), donc identique sur POST et sur PATCH partiel. Sans affretement,* l'adresse reste partielle (champs nullable, RG-4.06 inchangee).*/private function guardCharteredAddress(CarrierAddress $address): void🟢 RG-4.05 bien implémentée : garde portée par le processor (le parent affrété n'est pas disponible à la validation Symfony sur POST
read:false), uneConstraintViolationpar champ manquant (country/postalCode/city/street) avec propertyPath + message FR, levée viaValidationExceptionAPI Platform → rendu Hydra 422 mappable inline (ERP-101). Validation sur l'état résultant → cohérent POST et PATCH partiel. RAS.@@ -0,0 +63,4 @@self::assertResponseStatusCodeSame(422);}public function testCharteredCarrierIncompleteAddressReturns422(): void🟡 Rigueur d'assertion (cohérence avec #113). Les tests 422 (RG-4.06 et RG-4.05) n'assertent que le code HTTP, pas le
propertyPathdes violations. Or tout l'intérêt de RG-4.05 ici est le mapping par champ (city/streetinline, ERP-101) : une régression qui ferait perdre le propertyPath passerait au vert. La PR #113 assertait bien le path (assertViolationOnPath) — appliquer la même rigueur ici (vérifier que la 422 « affrété incomplet » porte des violations surcityETstreet).54ac034c1bto91dc02ab05POST /api/carriers/{id}/addresses + PATCH/DELETE /api/carrier_addresses/{id} (security transport.carriers.manage), spec-back § 4.5. Jumelle de SupplierAddress (M2) / ProviderAddress (M3), sans address_type ni M2M. - CarrierAddress : ajout #[ApiResource] (Get/Post/Patch/Delete) + groupe d'ecriture carrier:write:addresses + contraintes FR. RG-4.06 : code postal ^[0-9]{4,5}$ (Assert\Regex). Mapping ORM/colonnes inchange. - CarrierAddressProcessor : rattachement parent (404 si absent) + RG-4.05 (transporteur affrete -> Pays/CP/Ville/Adresse obligatoires, 422 par champ). RG-4.05 portee par le processor car le parent est indisponible a la validation Symfony sur un POST sous-ressource read:false. RG-4.07 = front (PATCH accepte). - EXCLUDED_LENGTH_MIRROR : CarrierAddress::postalCode (Regex borne la longueur). - Tests : CP invalide 422, affrete incomplet 422, affrete complet 201, PATCH/DELETE OK (manage), 403 sans manage.91dc02ab05to7012306a78