feat(front) : page Modification fournisseur (/suppliers/{id}/edit) (ERP-96) (#85)
Auto Tag Develop / tag (push) Successful in 7s
Auto Tag Develop / tag (push) Successful in 7s
## ERP-96 — Modification fournisseur Étape 7/7 (front). Dépend de #94 (Ajouter) + #95 (Consultation). > ⚠️ MR **stackée sur `feature/ERP-95-suppliers-show`** (95 → 94, pas encore mergées dans develop) pour limiter le diff aux 3 fichiers d'ERP-96. À recibler sur `develop` une fois 94 puis 95 mergées. Squash au merge. ### Périmètre - Route `/suppliers/{id}/edit` : champs **pré-remplis** depuis GET /suppliers/{id}, **PATCH partiel indépendant par onglet**. Bloc principal conservé (éditable via son propre PATCH `supplier:write:main`), pas de contact inline (ERP-106). - **Mode strict (RG-2.16)** : chaque onglet n'envoie QUE les champs de son groupe de sérialisation (jamais de mélange → sinon 403). Builders de payload scopés (`supplierEdit`). - Éditabilité par rôle (`resolveTabEditability`) : métier readonly sans `manage` ; Comptabilité visible/éditable selon `accounting.view`/`accounting.manage` ; placeholders non éditables. - Collections contacts/adresses/RIB : POST/PATCH par ligne + DELETE différé des retraits ; 422 mappées **inline par champ** (`propertyPath` → `useSupplierFormErrors`/`extractApiViolations`), jamais un toast fourre-tout (ERP-101). ### Tests - Vitest : `supplierEdit.spec.ts` enrichi (mappers d'hydratation `mapMainDraft`/`mapInformationDraft` avec `volumeForecast`/`mapAccountingFormDraft` + `resolveTabEditability` matrice § 2.7). `make nuxt-test` → 375/375 ✅. ESLint ✅. - `nuxi typecheck` non lancé sur l'hôte (casse le conteneur dev-nuxt). Miroir de l'écran Modification client (M1), adapté M2 (enum `addressType`, `bennes`/`triageProvider`/`volumeForecast`, pas de relation Distributeur/Courtier). Reviewed-on: #85 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #85.
This commit is contained in:
@@ -217,3 +217,28 @@ export function omitEmptyRequired<T extends Record<string, unknown>>(
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
/**
|
||||
* Variante PATCH (edition d'une ligne EXISTANTE) : remplace les cles requises
|
||||
* laissees vides par une chaine vide `''` au lieu de les OMETTRE.
|
||||
*
|
||||
* Pourquoi pas `omitEmptyRequired` en edition : un PATCH a semantique merge — une
|
||||
* cle absente laisse la valeur serveur INCHANGEE. Vider un champ requis puis valider
|
||||
* renverrait alors un 200 trompeur (l'ancienne valeur est conservee). En envoyant
|
||||
* `''`, la propriete `?string` est bien deserialisee (pas de 400 de type, contrairement
|
||||
* a `null` sur une colonne non-nullable), puis le Validator `NotBlank(trim)` la rejette
|
||||
* -> 422 avec propertyPath, mappee inline sous le champ. Mute et retourne le payload.
|
||||
*/
|
||||
export function blankEmptyRequired<T extends Record<string, unknown>>(
|
||||
payload: T,
|
||||
requiredKeys: readonly string[],
|
||||
): T {
|
||||
for (const key of requiredKeys) {
|
||||
const value = payload[key]
|
||||
if (value === null || value === undefined || value === '') {
|
||||
(payload as Record<string, unknown>)[key] = ''
|
||||
}
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user