[ERP-76 + ERP-68] Validations d'adresse client (RG → 422) + fixtures démo Catalog/Commercial #41
Reference in New Issue
Block a user
Delete Branch "feature/ERP-76-68-client-address-validations-fixtures"
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?
Stack de 2 tickets sur une branche (squash sur
develop).ERP-76 (#500) — Validations d'adresse Client → 422
Les règles d'intégrité de l'onglet Adresse étaient soit non implémentées (RG-1.29), soit rejetées en 500 par les CHECK Postgres (RG-1.06/07/08/11). Elles sont désormais portées par des
Assert\Callbackapplicatifs surClientAddress, qui remontent une 422 Hydra avant la base ; les CHECK BDD restent en filet de sécurité.validateProspectExclusivity—isProspectexclusif deisDelivery/isBilling(RG-1.06/07/08).validateBillingEmailPresence—billingEmailobligatoire ssiisBilling(RG-1.11).validateCategoryTypes— refuse une catégorie de type DISTRIBUTEUR/COURTIER sur une adresse (RG-1.29, violationcategories), viaCategoryInterface(règle n°1 respectée).Tests
ClientAddressTestdurcis (≥400 → 422 explicite) + 4 cas RG-1.29. Cahier de test M1 mis à jour.ERP-68 (#486) — Fixtures démo Catalog + Commercial (dev only)
CategoryFixtures(Catalog) : 12 catégories sur les 4 types.ClientFixtures(Commercial) : 14 clients couvrant les cas RG (dépendant distributeur/courtier RG-1.03, LCR + 2 RIB RG-1.13, Chèque sans RIB, multi-adresses Prospect/Livraison/Facturation RG-1.06/07/08/11, prospect seul, 3 contacts + tél. secondaire RG-1.05/1.02, archivé RG-1.22, onglet Information complet, multi-catégories M2M).Résolution inter-modules via les seuls contrats Shared (
CategoryInterface,SiteProviderInterface). Valeurs brutes normalisées parClientFieldNormalizer. Données conformes aux CHECK BDD et aux validators ERP-76. Idempotentes (lookupcompanyName/name). Garde-fou : les deux fixtures sont no-op en environnementtest(la base de test reste un socle minimal ; pas de pollution des comptages ni des cleanups FK).Bonus — idempotence fixtures
AppFixtures(admin/alice/bob) rendu idempotent via lookup par username :doctrine:fixtures:load --appendest désormais rejouable sans erreur sur tout le jeu de fixtures.Vérifications
make test: 436/436 vert (0 échec/erreur).make php-cs-fixer-allow-riskyOK.make db-resetcharge sans erreur ; 2 runs--appendconsécutifs = idempotent (0 doublon ; 7 users / 14 clients / 12 catégories stables).admin/adminintact.Review MR #41 — ERP-76 + ERP-68
Verdict : MR de très bonne qualité, bien documentée, tests solides. Un bug de correctness a été trouvé et corrigé directement sur la branche (commit
e618853). Le reste n'est qu'observations mineures non bloquantes.🔴 Majeur — corrigé dans
e618853:billingEmailvide → 500 au lieu de 422 (RG-1.11)validateBillingEmailPresence(ClientAddress.php) testaitnull === $this->billingEmail. Une chaîne vide""(cas courant d'un champ de formulaire vidé) passait donc les validators :#[Assert\Email]accepte""(valide sansNotBlank) ;null === ""est faux ;ClientAddressProcessornormalise ensuite""→nullaprès la validation (RG-1.21) ;is_billing=true+billing_email=nullviole le CHECKchk_client_address_billing_email→ 500 DBAL.C'est précisément la régression « 500 au lieu de 422 » que ce ticket entend supprimer. Symétriquement,
""sur une adresse non facturable était rejeté à tort en 422 alors qu'un champ vide équivaut à une absence d'email.Fix : le callback raisonne désormais sur la présence effective (
nullou chaîne vide aprèstrim= absent), cohéremment avec la normalisation du processor. Deux cas de test ajoutés (ClientAddressTest) :""→ 422 ;""→ 201.🟡 Mineur (observation, non corrigé) — règle n°1 dans
ClientFixtures::getDependencies()getDependencies()référenceCategoryFixtures::class(Catalog) etSitesFixtures::class(Sites), soit un couplage inter-modules au sens strict de la règle n°1. En pratique c'est purement de l'ordonnancement de fixtures (FQCN, aucune logique métier cross-module ; la résolution métier passe bien par les contratsCategoryInterface/SiteProviderInterface). Acceptable, mais mériterait soit une exception explicitement documentée, soit — si on veut être puriste — un marqueur d'ordonnancement dansShared/. Non bloquant.🟢 Points vérifiés sans réserve
DISTRIBUTEUR/COURTIER(uniquement SECTEUR/AUTRE). Conforme.nameseul : non ambiguë (les noms sont uniques inter-types dansCategoryFixtures). À garder en tête si des noms dupliqués apparaissent un jour entre types.--append:AppFixtures::ensureUser+addSite/addRbacRoledédupliquent viacontains()→ pas de doublon en table de jointure.ensureClient/ensureCategorylookup aligné sur les index uniques partiels. OK.test:CategoryFixturesetClientFixturesno-op entest. OK.validateProspectExclusivity/validateCategoryTypes: logique sans trou.Vérifications post-fix
make test: 438/438 vert (436 d'origine + 2 nouveaux cas).make php-cs-fixer-allow-risky: 0 fichier à corriger.Une fois le CI revert, la MR est mergeable en l'état.