Files
Starseed/docs/specs/M4-transporteurs/spec-front.md
T
Matthieu d9313dbec8 feat(transport) : schéma + entités Carrier + contrat lecture (ERP-155/157)
Schéma BDD du répertoire transporteurs (M4) + entités + contrat de lecture
(liste + détail), socle du front.

- Migration Version20260615150000 : tables carrier / carrier_address /
  carrier_contact / carrier_price (FK cross-module, CHECK enum, index partiel
  uq_carrier_name_active, COMMENT ON COLUMN). uploaded_document et
  qualimat_carrier réutilisées (non recréées).
- Entités Carrier* (#[Auditable], Timestampable/Blamable) + ApiResource
  LECTURE seule (GetCollection + Get via CarrierProvider, anti-N+1, exclusion
  archivés + ?includeArchived). Écriture (POST/PATCH + Processor) reportée WT4+.
- QualimatCarrier : mapping ORM lecture seule sur la table référentielle
  existante (sortie du schema_filter, mapping aligné DDL ERP-39, schema:update
  no-op) + endpoint de recherche read-only (§ 4.7).
- Relations cross-module des prix (Client/Supplier/adresses) via contrats
  Shared (ClientInterface, SupplierInterface, ClientAddressInterface,
  SupplierAddressInterface) + resolve_target_entities — sans import inter-module
  (règle n°1). Ajout du groupe supplier_address:read aux champs de
  SupplierAddress pour l'embed.
- Garde-fous : ColumnCommentsCatalog (carrier* + qualimat_carrier), makefile
  test-db-setup (index partiel carrier), i18n audit (transport_carrier*),
  EntitiesAreTimestampableBlamableTest (QualimatCarrier whitelisté).
- CarrierSerializationContractTest : contrat JSON liste + détail vérifié
  (embeds objet, booléens, enveloppe Hydra) ; JSON réel capturé dans
  spec-back § 4.0.bis.

make db-reset OK, make test vert (731), make nuxt-test vert (480),
php-cs-fixer OK.
2026-06-15 19:15:12 +02:00

23 KiB

module, nom, ecran, owner_spec, backup_spec, version, date_redaction, maquette_figma, regles_metier, roles, lien_spec_back, client_validation_1, lesstime_project_id, lesstime_taskgroup_id, statut_global
module nom ecran owner_spec backup_spec version date_redaction maquette_figma regles_metier roles lien_spec_back client_validation_1 lesstime_project_id lesstime_taskgroup_id statut_global
M4 Répertoire transporteurs repertoire-transporteurs Matthieu Tristan V0.1 2026-06-15 https://www.figma.com/design/jRYgT0T9c03VsEbjGhCwwS/Composants---Design-System?node-id=1132-45376&p=f&m=dev
RG-4.01
RG-4.02
RG-4.03
RG-4.04
RG-4.05
RG-4.06
RG-4.07
RG-4.08
RG-4.09
RG-4.10
RG-4.11
Admin
Bureau
Compta
Commerciale
Usine
./spec-back.md
statut date version valide_par
validee 2026-05-27 V0 Matthieu (CP MALIO)
6 31 pret_a_dev

Module 4 — Répertoire transporteurs (V0.1 front)

Origine : spec fonctionnelle M4-repertoire-transporteurs-V0 (validée le 27/05/2026) + maquette Figma. Restitution Markdown pour intégration au workflow MALIO. Toute décision technique (back) vit dans spec-back.md. Le M4 réutilise le pattern et les composants posés aux M1 clients, M2 fournisseurs et M3 prestataires.

Socle déjà en place : le module back Transport existe (ERP-150) et porte deux référentiels synchronisés par commandes console : transporteurs QUALIMAT (qualimat_carrier, ERP-39) et codes IDTF (idtf_product, ERP-149). Le M4 ajoute le répertoire éditable (Carrier) par-dessus ces référentiels — la saisie assistée du nom interroge le référentiel QUALIMAT (RG-4.01). L'IDTF n'est pas utilisé par ces écrans.

Décisions Matthieu (15/06/2026) : (1) lien QUALIMAT = FK + copie éditable des champs (nom / certification / adresse) ; (2) pas de cloisonnement par site (référentiel global) ; (3) le champ « Décharge » s'appuie sur une infra d'upload réutilisable (Shared), car d'autres uploads suivront. Détails : spec-back.md § 2.5 / § 2.3 / § 2.7.

But

Lister tous les transporteurs de l'organisation et accéder rapidement à leurs fiches : consultation, création, modification, archivage. Le nom est relié à QUALIMAT (saisie assistée) ; les transporteurs hors QUALIMAT (GMP+, OVOCOM, compte-propre, LIOT, autre) sont saisis manuellement.

Accès

  • Depuis : menu principal → section Transport (route /carriers). (Section « Transport » dédiée ou rattachement à une section « Logistique » — à confirmer, cf. spec-back.md § 5.3.)
  • Rôles autorisés (tableau « Rôles & permissions » du docx) :
Rôle Consultation Ajout / Modification Archive
Admin Tout Tout
Bureau Tout Tout
Compta
Commerciale Tout
Usine

Notes :

  • RBAC transposée sur transport.carriers.* (cf. spec-back.md § 5). Commerciale = consultation seule (pas de « + Ajouter » ni « Modifier »). Compta et Usine n'ont aucun accès au module (item sidebar masqué).
  • Pas de cloisonnement par site (≠ M3) : tout rôle autorisé voit tous les transporteurs.

Navigation

Page d'entrée du module Transport (route /carriers). Titre : « Répertoire transporteurs ».

  • Affichage principal : un datatable listant tous les transporteurs actifs (les archivés sont masqués par défaut — filtre dédié).
  • Clic sur une ligne → écran Consultation transporteur (page dédiée).
  • Bouton « + Ajouter » (haut droite, si manage) → écran Ajouter un transporteur.
  • Bouton « Filtrer » (haut droite) → panneau de filtres.
  • Bouton « Exporter » (haut droite) → télécharge un XLSX des transporteurs affichés (cf. filtres actifs). Format dans spec-back.md § 4.6.

Panneau de filtres (bouton « Filtrer »)

Réutilise le pattern M1/M2/M3. Filtres branchés sur les query params de GET /api/carriers (cf. spec-back.md § 4.1) :

Filtre Composant Query param back
Recherche (nom) <MalioInputText> ?search=
Certification <MalioSelectCheckbox> (QUALIMAT / GMP+ / OVOCOM / Compte-propre / Autre) ?certificationType=
Inclure les archivés <MalioCheckbox> ?includeArchived=true
  • À l'application des filtres → setFilters(...) de usePaginatedList (retombe en page 1).
  • État 100 % local (jamais dans l'URL — règle ABSOLUE n°6).

Datatable du Répertoire

Composant : <MalioDataTable> branché sur usePaginatedList<Carrier>({ url: '/carriers' }) (règle frontend obligatoire — pagination Hydra, état 100 % local). Colonnes :

Colonne Source Tri
Nom carrier.name ASC par défaut
Certification carrier.certificationType (libellé i18n) Non
Date de validité carrier.qualimatCarrier.validityDate (format JJ-MM-AAAA) — fond rouge si < aujourd'hui (RG-4.04) Non
Dernière activité carrier.updatedAt (format JJ-MM-AAAA) Oui

Clic sur une ligne → écran Consultation. Pagination : standard Starseed 10 / 25 / 50 (défaut 10). Tri serveur name ASC par défaut.

Écran « Ajouter un transporteur »

Création par onglets successifs avec validation incrémentale : pour passer à l'onglet suivant, il faut avoir validé l'onglet en cours. Une fois un onglet validé, on passe automatiquement au suivant ; les champs validés passent en lecture seule. L'onglet Adresses n'est accessible qu'une fois le formulaire principal validé. Cf. spec-back.md § 2.9 (PATCH partiels par groupe de sérialisation).

Accès : bouton « + Ajouter » du Répertoire. Rôles : Admin, Bureau.

Barre d'onglets : Qualimat · Adresses · Contacts · Prix.

Formulaire principal (pré-onglets)

1er bloc à remplir. Sans validation, les onglets ne sont pas accessibles. Une fois validé → POST /api/carriers, puis bascule sur l'onglet Qualimat/Adresses ; les champs passent en readonly.

Champ Type composant Obligatoire Règle
Nom (saisie assistée reliée à QUALIMAT) <MalioInputText> (autocomplete) Oui RG-4.01 ; RG-4.13 (UPPERCASE serveur) ; RG-4.12 (unicité)
Liste certification transport <MalioSelect> (GMP+ / OVOCOM / Compte-propre / Autre) Oui RG-4.02 ; auto = QUALIMAT (lecture seule) si transporteur QUALIMAT sélectionné
Affréter <MalioCheckbox> Non RG-4.03
Indexation % <MalioInputNumber> Conditionnel RG-4.03 — visible + obligatoire si « Affréter » coché
Benne / Fond mouvant <MalioRadioButton> Conditionnel RG-4.03 — visible + obligatoire si « Affréter » coché
Volume m³ <MalioInputNumber> Conditionnel RG-4.03 — visible + obligatoire si « Affréter » coché
Décharge <MalioInputUpload> (cf. note) Conditionnel (obligatoire si AUTRE) RG-4.02 — visible et obligatoire si certification = AUTRE. Upload via infra Shared (spec-back.md § 2.7)
Liste immatriculation LIOT <MalioInputText> (ou TextArea) Cas LIOT RG-4.01 — visible uniquement si nom = LIOT ; les autres champs disparaissent. Immatriculations séparées par ;

Comportement RG-4.01 (saisie assistée) : à la saisie du nom, recherche dans le référentiel QUALIMAT via GET /api/qualimat_carriers?search=. Sélection d'un résultat → modal de confirmation « Êtes-vous sûr de vouloir intégrer ce transporteur ? ». Si confirmé : le Nom et la certification (= QUALIMAT, lecture seule) se remplissent automatiquement, ainsi que l'onglet Adresse (copie pays/CP/ville/voie depuis le référentiel). La FK QUALIMAT est conservée (traçabilité + date de validité RG-4.04).

  • Cas transporteur non trouvé (pas QUALIMAT) : l'utilisateur choisit une autre certification (RG-4.02) → affichage des champs associés.
  • Cas LIOT : si le nom saisi est exactement LIOT, seul le champ « Liste immatriculation LIOT » s'affiche, les autres champs sont masqués.

Note <MalioInputUpload> : si le composant ne couvre pas le drag & drop / type fichier requis, exception autorisée documentée (// TODO migrer quand Malio couvre) — cf. exceptions @.claude/rules/frontend.md.

Action : « Valider » (<MalioButton>) → POST /api/carriers (spec-back.md § 4.3). Succès → onglet « Qualimat » / « Adresses ».

Onglet « Qualimat »

Sélectionner un transporteur de la liste QUALIMAT afin de mettre à jour les informations du transporteur (saisie assistée — voir RG-4.01).

Colonnes du tableau de sélection :

Colonne Règle
Sélection (bouton / clic ligne) RG-4.03 (docx) — clic → modal « Êtes-vous sûr de vouloir intégrer ce transporteur ? » → remplit Nom + certification + onglet adresse
Nom
Adresse
Date de validité RG-4.04 — fond rouge si < date du jour

Cet onglet alimente le formulaire principal et l'onglet Adresse par copie (RG-4.01 / RG-4.05). Source : GET /api/qualimat_carriers?search= (lecture seule, lignes actives uniquement).

Onglet « Adresses »

Saisir l'adresse du transporteur (un bloc par adresse).

Champ Type Obligatoire Règle
Pays <MalioSelect> (préremplie « France ») Conditionnel RG-4.05
Code postal <MalioInputText> (saisie assistée) Conditionnel RG-4.06, RG-4.05 — déclenche autocomplete ville (BAN)
Ville <MalioSelect> (saisie assistée) Conditionnel RG-4.06, RG-4.05 — alimentée par api-adresse.data.gouv.fr
Adresse <MalioInputText> (saisie assistée) Conditionnel RG-4.05
Adresse complémentaire <MalioInputText> Non

RG-4.05 : les champs sont déjà remplis si le transporteur est QUALIMAT (copie). Si « Affréter » est coché, l'adresse devient obligatoire (Pays, Code postal, Ville, Adresse). RG-4.06 : la ville est préremplie automatiquement à partir du code postal via l'API BAN (useAddressAutocomplete(), réutilisé M1/M2/M3). Si plusieurs villes → choix dans le select. L'adresse est une saisie assistée basée sur le CP et la ville. RG-4.07 : le bouton « Valider » n'apparaît pas pour un transporteur QUALIMAT (adresse remplie automatiquement).

Actions : « Valider » → PATCH /api/carriers/{id}/addresses (sauf QUALIMAT, RG-4.07).

Onglet « Contacts »

Saisir un ou plusieurs contacts associés au transporteur.

Champ Type Obligatoire Règle
Nom <MalioInputText> Non RG-4.08 + RG-4.13 (Capitalize)
Prénom <MalioInputText> Non RG-4.08 + RG-4.13 (Capitalize)
Fonction <MalioInputText> Non RG-4.08
Téléphone (x1, +1 possible, max 2) <MalioInputText> Non RG-4.08 + RG-4.13 (format)
Email <MalioInputText> type email Non RG-4.08 + RG-4.13 (lowercase)

RG-4.08 : un bloc Contact est valide dès qu'au moins 1 champ est rempli. Impossible d'ajouter un nouveau bloc tant que le précédent n'est pas valide.

Actions :

  • « + Nouveau contact » : ajoute un bloc. Désactivé tant que le bloc précédent n'a aucun champ rempli (RG-4.08).
  • « Supprimer » (icône) : modal de confirmation, puis suppression du bloc.
  • « Valider » → PATCH /api/carriers/{id}/contacts.

Onglet « Prix »

Saisir un suivi de prix du transporteur (un bloc par prix). Tous les champs sont masqués par défaut sauf le radio « Client / Fournisseur » (RG-4.09).

Bloc Prix :

Champ Type Obligatoire Règle
Client / Fournisseur <MalioRadioButton> Oui RG-4.09
Client <MalioSelect> (liste des clients) Conditionnel RG-4.10 — si Client
Adresse de livraison <MalioSelect> (adresses du client sélectionné) Conditionnel RG-4.10 — si Client
Adresse de départ <MalioSelect> (86 / 17 / 82) Conditionnel RG-4.10 — si Client ; = un des 3 sites
Fournisseur <MalioSelect> (liste des fournisseurs) Conditionnel RG-4.11 — si Fournisseur
Adresse d'approvisionnement <MalioSelect> (adresses du fournisseur) Conditionnel RG-4.11 — si Fournisseur
Adresse de livraison <MalioSelect> (86 / 17 / 82) Conditionnel RG-4.11 — si Fournisseur ; = un des 3 sites
Benne / Fond mouvant (FM) <MalioRadioButton> Oui
Forfait / Tonne <MalioRadioButton> Oui
Prix <MalioInputAmount> (monnaie) Oui
État du prix <MalioSelect> (En cours / Validé / Non validé) Oui

RG-4.10 : si Client sélectionné → champs liés au client affichés et obligatoires ; champs fournisseur masqués et non obligatoires. RG-4.11 : si Fournisseur sélectionné → champs liés au fournisseur affichés et obligatoires ; champs client masqués et non obligatoires. Adresse de départ / livraison « 86 / 17 / 82 » = les 3 Site fixes (cf. switcher de site Châtellerault / Saint-Jean / Pommevic en haut de l'app). La sélection stocke un ID de Site (spec-back.md § 3.2).

Actions :

  • « + Nouveau prix » : ajoute un bloc. Bloqué tant que le précédent n'est pas valide.
  • « Supprimer » (icône) : modal de confirmation puis suppression.
  • « Valider » → PATCH /api/carriers/{id}/prices.

Écran « Consultation d'un transporteur »

Consulter en lecture seule la fiche complète. Affiche en haut du bloc les infos principales du transporteur (comme l'écran d'ajout) ainsi que les onglets Adresses, Contacts, Prix. Tous les champs sont en lecture seule.

Accès : clic sur une ligne du Répertoire. La page s'ouvre par défaut sur l'onglet Adresses. Icône « flèche » à gauche pour revenir au répertoire. Deux boutons à droite :

  • « Modifier » (visible si transport.carriers.manage → Admin, Bureau).
  • « Archiver » (visible uniquement Admin via transport.carriers.archive) → modal de confirmation, puis PATCH /api/carriers/{id} { "isArchived": true }.

Un transporteur archivé peut être restauré (isArchived: false) — bouton « Restaurer » remplace « Archiver » dans la consultation d'un archivé.

Onglet Adresses (consultation)

Un bloc par adresse du transporteur. Chaque bloc, 5 champs en lecture seule : Pays / Code postal / Ville / Adresse / Adresse complémentaire.

Onglet Contacts (consultation)

Un bloc par contact. 5 champs en lecture seule : Nom / Prénom / Fonction / Téléphone (x1 ou x2) / Email.

Onglet Prix (consultation)

Un tableau regroupant les prix par type (Fond Mouvant / Benne) :

Colonne Description
Colonne de regroupement « Fond Mouvant » / « Benne »
Transporteurs Nom du transporteur
Adresse APRO ou Adresse Sites Si prix « Client » → Adresse APRO sinon Adresse Sites
Adresse livraisons
Forfait € Prix
Tonne € Prix
Indexation Pourcentage d'indexation (vide si non rempli)
État du prix Validé / Non Validé / En cours

Action : « Exporter » → exporte le tableau au format Excel (GET /api/carriers/{id}/prices/export.xlsx).

Écran « Modification d'un transporteur »

Modifier les informations d'un transporteur existant. Identique à l'écran « Ajouter un transporteur » — mêmes formulaires, mêmes règles métier (RG-4.01 à RG-4.11) — sauf :

  • Les champs sont pré-remplis avec les valeurs actuelles.
  • Validation par onglet : on peut modifier UN onglet sans toucher aux autres (PATCH partiel).
  • Accès : depuis l'écran Consultation, bouton « Modifier » (Admin, Bureau).

Composants UI à utiliser (@malio/layer-ui)

  • Datatable : <MalioDataTable> (+ usePaginatedList)
  • Input texte : <MalioInputText>
  • Input nombre / montant : <MalioInputNumber> (indexation, volume), <MalioInputAmount> (prix)
  • Select simple : <MalioSelect> (certification, pays, ville, client, fournisseur, adresses, sites, état du prix)
  • Select multi (cases à cocher) : <MalioSelectCheckbox> (filtres certification)
  • Radio : <MalioRadioButton> (Benne/Fond mouvant, Forfait/Tonne, Client/Fournisseur)
  • Checkbox : <MalioCheckbox> (Affréter, inclure archivés)
  • Upload : <MalioInputUpload> (Décharge — exception documentée si type non couvert)
  • Bouton : <MalioButton>, <MalioButtonIcon>
  • Toasts : standards via useApi()
  • Validation par champ : useFormErrors (mapping 422 inline — règle frontend obligatoire)

Exceptions autorisées (commenter // TODO migrer quand Malio couvre) :

  • Modal de confirmation : wrapper partagé dans frontend/shared/ (réutiliser celui du M1/M2/M3).
  • <MalioInputUpload> si le type fichier / drag & drop n'est pas couvert.

Composables & appels API

  • usePaginatedList<Carrier>({ url: '/carriers' }) — liste paginée (obligatoire). Consomme name, certificationType, qualimatCarrier.validityDate (RG-4.04), updatedAt (cf. spec-back.md § 2.11 / § 4.0).
  • useCarrier(id) — charge le détail via GET /api/carriers/{id}, qui embarque addresses, contacts, prices (avec client/supplier/sites imbriqués) + qualimatCarrier. Écrans Consultation et Modification peuplés depuis cette seule réponse. DoD avant intégration : vérifier le JSON réel (cf. spec-back.md § 4.0.bis).
  • useCarrierForm() — workflow par onglet (POST principal + PATCH partiels par groupe), miroir de useSupplierForm()/useProviderForm() + gestion des champs conditionnels (Affréter, AUTRE→Décharge, cas LIOT).
  • useQualimatSearch() — saisie assistée du nom : GET /api/qualimat_carriers?search=, modal de confirmation, copie des champs + FK (RG-4.01).
  • useAddressAutocomplete()réutilisé du M1/M2/M3 (BAN), pas de réécriture (RG-4.06).
  • useUpload() (NOUVEAU, infra Shared) — POST multipart /api/uploaded_documents → renvoie l'IRI à poser sur carrier.dischargeDocument (RG-4.02).
  • usePermissions() — masque l'item sidebar et les boutons selon les permissions.
  • Tous les appels passent par useApi() (jamais $fetch direct — règle ABSOLUE n°4).
  • Filter formatPhoneFR()réutilisé pour l'affichage XX XX XX XX XX.

Règles de formatage et normalisation

Le serveur normalise systématiquement (RG-4.13 — cf. spec-back.md) :

Champ Normalisation serveur Affichage front
Nom transporteur (name) UPPERCASE intégral UPPERCASE
Nom + Prénom contact Capitalize identique
Téléphones (CarrierContact) Chiffres uniquement en BDD Formaté XX XX XX XX XX (filter Vue)
Email lowercase intégral identique
Immatriculations LIOT ;-split, trim, UPPER listées

Le front ne normalise pas : il envoie la valeur saisie, le serveur normalise et renvoie la valeur normalisée que l'UI affiche.

API adresse postale

Code postal + Ville + Adresse branchés sur api-adresse.data.gouv.fr (BAN) via le composable useAddressAutocomplete() déjà créé au M1/M2/M3 (réutilisé tel quel) :

  • À la saisie du CP (5 chiffres) : GET https://api-adresse.data.gouv.fr/search/?q={cp}&type=municipality → alimente le select Ville (RG-4.06 : si plusieurs villes, choix dans le select).
  • À la saisie d'adresse : ?q={addr}&postcode={cp}&type=housenumber → suggestions.
  • Cas dégradé (timeout / offline) : Ville en <MalioInputText> libre + toast d'avertissement.

Différences notables avec les modules précédents

Zone M2/M3 M4 transporteurs
Source du nom saisie libre saisie assistée reliée à QUALIMAT (référentiel synchronisé)
Onglet Comptabilité / RIB présent (M2/M3) Absent
Cloisonnement par site M3 : oui Non (référentiel global)
Champs conditionnels formulaire principal peu Nombreux (Affréter, AUTRE→Décharge, cas LIOT)
Onglet Prix absent Présent (Client/Fournisseur, sites départ/livraison)
Upload de fichier aucun Décharge (infra upload Shared, réutilisable)
Module Commercial / Technique Transport (existant, ERP-150)

Points résolus côté back

# Zone d'ombre Résolution (cf. spec-back.md)
1 Lien QUALIMAT FK qualimatCarrier + copie éditable des champs (§ 2.5)
2 Cas LIOT Champ liotPlates (;-séparé), autres champs masqués (RG-4.01)
3 Certification QUALIMAT Valeur QUALIMAT lecture seule si lié (§ 2.5)
4 Décharge (upload) Infra upload générique Shared réutilisable (§ 2.7)
5 Onglet Prix — branches M2M absentes : FK Client/Supplier + adresses + sites (RG-4.10/4.11, § 3.2)
6 Adresse de départ/livraison 86/17/82 = les 3 Site fixes (FK Site)
7 Workflow par onglet Sauvegarde incrémentale (POST principal + PATCH partiels) — pas d'état « draft »
8 Archive vs delete Flag is_archived séparé ; archivage Admin seul ; soft delete = HP
9 Unicité métier Nom seul (§ 2.6)
10 Référentiel QUALIMAT Endpoint lecture seule GET /api/qualimat_carriers?search= (§ 4.7)
11 Format export XLSX (répertoire + onglet Prix regroupé Benne/FM)
12 RBAC transport.carriers.view/manage/archive ; Compta + Usine sans accès (§ 5.2)

📦 Tickets Lesstime

TaskGroup Lesstime : à créer — M4 — Répertoire transporteurs (projet ERP / Starseed, projectId=6). Découpe détaillée (back en tête) → spec-back.md § Tickets Lesstime.

Ordre Sujet Tag
0 Permissions transport.carriers.* + sidebar + 3 sources RBAC Backend
1 Infra upload générique Shared (uploaded_document + FileUploader + endpoint) Backend
2 Migration BDD M4 (carrier + sous-collections + index + COMMENT) Backend
3 Entité QualimatCarrier (lecture seule) + endpoint recherche Backend
4 Entités + Repositories Carrier* Backend
5 CarrierProvider + CarrierProcessor (champs conditionnels, archive, LIOT) Backend
6 Sous-ressources Adresses / Contacts / Prix (RG-4.10/4.11) Backend
7 Export XLSX (répertoire + onglet Prix) Backend
8 Tests PHPUnit RG-4.01→4.14 + capture contrat JSON Backend
9 Page Répertoire (/carriers) + usePaginatedList Frontend
10 Page Ajouter + formulaire principal + saisie assistée QUALIMAT Frontend
11 Onglets Adresses (BAN) / Contacts / Prix Frontend
12 Pages Consultation + Modification Frontend
13 i18n + libellés audit + upload front (useUpload) Frontend