feat(front) : mapping des erreurs de validation 422 par champ (ERP-101) #58
Reference in New Issue
Block a user
Delete Branch "feat/ERP-101-form-field-validation-mapping"
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?
Objectif
Afficher les violations de validation 422 du back sous chaque champ (prop
:errordesMalio*) au lieu d'un toast global, et poser une convention reutilisable par tous les forms.Contenu
mapViolationsToRecord(util pur) + composableuseFormErrors(etat d'erreurs parpropertyPath,setServerErrors/handleApiError: 422 inline, sinon toast de fallback).new.vue+[id]/edit.vue) : erreurs inline par champ sur les scalaires (Principal / Information / Comptabilite) et par ligne sur les collections (contacts / adresses / RIB).ClientContactBlock/ClientAddressBlock: nouvelle properrors.useCategoryFormsuruseFormErrors(drawer adapte,_global-> toast)..claude/rules/frontend.md+ spec de design.Suivi
messageFR, contraintes manquantes, violations sanspropertyPath).Tests
api,useFormErrors,ClientContactBlock,ClientAddressBlock;useCategoryForm28/28 apres migration).nuxi typecheck0 erreur.--no-verify: flake JWT 401 connu du hook, sans rapport).Revue — approuvée ✅
PR propre et bien construite.
useFormErrors+mapViolationsToRecordposent une convention claire et réutilisable, la gestion d'erreur est rigoureuse (catch externes conservés sur les boucles de suppression, erreurs de collection alignées par index sur lev-for, splice des erreurs au retrait d'une ligne). Le bump@malio/layer-ui1.7.4 fournit bienreadonly/requiredsurMalioSelect/SelectCheckboxetmax-visible-tabs/max-widthsurMalioTabList, donc le swap:disabled→:readonlyne casse aucun verrouillage. Lockfile recorrigé (ec0855d), CI verte (back + front).Aucun bloquant. 2 suggestions mineures optionnelles en commentaires inline (i18n + factorisation). 👍
@@ -581,0 +629,4 @@* index). 422 exploitable → erreurs inline sous les champs de la ligne ; sinon* → toast de fallback. Renvoie true si mappee inline.*/function mapRowError(🟡 Mineur (altitude) — copie de
mapRowErrordenew.vue(cf. commentaire là-bas). Candidat à un composable partagéuseClientFormErrors(). Non bloquant.@@ -394,0 +444,4 @@* index). 422 avec violations exploitables → erreurs inline sous les champs de* la ligne ; sinon → toast de fallback. Renvoie true si mappee inline.*/function mapRowError(🟡 Mineur (altitude) —
mapRowError+ le câblage des erreurs par ligne (contactErrors/addressErrors/ribErrors+ lesuseFormErrorsscalaires) sont quasi identiques entrenew.vueet[id]/edit.vue. Dans l'esprit « convention réutilisable » de cette PR, unuseClientFormErrors()partagé éviterait la divergence future (seul le fallback diffère :toast.errorici vsshowErroren edit). Non bloquant.@@ -0,0 +96,4 @@= extractApiErrorMessage(data)|| opts.fallbackMessage|| 'Une erreur est survenue.'toast.error({ title: 'Erreur', message })🟡 Mineur (i18n) — libellés en dur dans un composable partagé :
title: 'Erreur'et le fallback'Une erreur est survenue.'. Le reste du projet passe part(...). CommeuseFormErrorsest appelé dans un contexte de composant, on peut y faireconst { t } = useI18n()et exposer les libellés via i18n (ou les passer en option) pour rester cohérent avec la convention. Non bloquant.Merci pour la review 🙏 Les 2 suggestions mineures sont traitées dans
97fe0b3:🟡 i18n (useFormErrors) — fait. Les libellés de toast génériques passent par i18n : nouvelles clés
errors.title/errors.generic/errors.unknown/success.title, consommées viauseI18n(). Tant qu'à faire, j'ai aussi alignéuseApi(qui hardcodait les mêmes'Erreur'/'Succes'/'Erreur inconnue.') etuseCategoryForm, pour une cohérence totale plutôt qu'un fix partiel.🟡 factorisation (mapRowError + état par ligne) — fait. Nouveau composable partagé
useClientFormErrors()(modules/commercial/composables/) : il porte les 3useFormErrorsscalaires + les 3 tableaux d'erreurs par ligne +mapRowError. Pour gérer le fallback divergent,mapRowErrorretourne désormais un booléen (true= mappé inline) et ne toaste plus : chaque page garde son propre fallback dans lecatch(toast générique en création,showErroren édition).new.vueet[id]/edit.vuene dupliquent plus le câblage. Test Vitest dédié ajouté.Vérifs : Vitest 216/216 (dont le nouveau spec
useClientFormErrors), eslint clean,nuxi typecheck0 erreur.