Files
Starseed/docs/specs/M1-clients/refonte-contact/README.md
T
Matthieu 83508d0c5a
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m39s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m5s
docs(commercial) : refonte contact — suppression du contact inline (specs M1 + M2)
Le contact principal inline (firstName/lastName/phonePrimary/phoneSecondary/email)
est retiré des entités tiers : il vit désormais uniquement dans ClientContact /
SupplierContact (onglet Contacts).

- M1 (spec-back / spec-front / cahier-test) : contact inline retiré du modèle Client ;
  RG-1.01 et RG-1.02 marquées supprimées (équivalent RG-1.05 / RG-1.14) ; décisions
  D1 (recherche) et D2 (export) décrites ; version V1.
- M2 (spec-back / spec-front) : contact inline retiré du modèle Supplier dès la
  conception ; RG-2.01 et RG-2.02 supprimées (équivalent RG-2.04 / RG-2.13) ; version
  V0.2. Fichiers M2 introduits ici car non encore versionnés sur develop.
- docs/specs/M1-clients/refonte-contact/ : décision (README) + tickets (M1 back/front/
  specs, M2 specs) + prompts d'implémentation + amendement des tickets M2 existants.
2026-06-03 15:11:45 +02:00

4.9 KiB
Raw Blame History

Refonte « contact » — suppression du contact inline des tiers (Client M1 + Supplier M2)

Dossier de tickets transverse. Source de vérité de la décision et de son découpage. Rédigé le 2026-06-03. Owner : Matthieu.

1. Décision

Le contact « principal » inline (les 5 colonnes plates first_name, last_name, phone_primary, phone_secondary, email) est supprimé de l'entité tier (Client, puis Supplier). La gestion des contacts passe exclusivement par la sous-entité dédiée (ClientContact / SupplierContact), c.-à-d. l'onglet « Contacts ».

Pourquoi

  • Modèle unique, zéro duplication. Aujourd'hui le contact est saisi deux fois : une fois dans le bloc principal (inline sur le tier) et une fois dans l'onglet Contacts (sous-entité). À la création, le front recopie même l'un dans l'autre (prefillFirstContact). Deux sources pour la même information = risque de divergence.
  • Cohérence métier. Un tier peut avoir plusieurs contacts ; il n'y a pas de raison qu'un seul soit « privilégié » au niveau de la table tier. La notion de contact appartient à la collection de contacts.
  • Garantie préservée. L'invariant « il y a toujours au moins un contact » est déjà assuré par la sous-entité : RG-1.05/RG-1.14 (M1) et RG-2.04/RG-2.13 (M2) imposent ≥ 1 bloc Contact valide (Nom OU Prénom). Supprimer le contact inline ne crée donc aucun trou : le contact reste obligatoire, mais au bon endroit.

Règles de gestion impactées

RG Avant Après
RG-1.01 / RG-2.01 (firstName OU lastName obligatoire sur le tier) sur Client / Supplier supprimée du tier — équivalent assuré par RG-1.05 / RG-2.04 sur la sous-entité
RG-1.02 / RG-2.02 (max 2 téléphones sur le tier) sur le tier supprimée du tier — reste sur la sous-entité
RG-1.19/1.20/1.21 — RG-2.12 (normalisation Capitalize / chiffres / lowercase) appliquée aux champs du tier ET de la sous-entité ne s'applique plus aux champs du tier (qui n'existent plus) — inchangée sur la sous-entité

2. Périmètre & découpage

M1 — Clients (code DÉJÀ livré → suppression + migration de données)

# Ticket Tag Effort
1 M1-ticket-01-back — supprimer le contact inline du Client (migration + backfill + entité + processor + provider + export + fixtures + tests) Backend M
2 M1-ticket-02-front — retirer le bloc contact principal des écrans création / consultation / modification Frontend M
3 M1-ticket-03-specs — acter la décision dans les specs M1 (back + front + cahier de test) Maintenance S

M2 — Fournisseurs (NON codé → on retire le contact inline dès la conception)

# Action Tag Effort
4 M2-ticket-specs — mettre à jour les specs M2 déjà écrites (back + front) pour retirer le contact inline du Supplier Maintenance S
M2-amendement-tickets — amender les tickets M2 existants (n° 8497) impactés (migration, entités, processor, export, front, tests, i18n)

M2 ne nécessite pas de migration de suppression ni de backfill : il suffit de ne jamais créer les 5 colonnes inline sur supplier. Le travail M2 est donc un ajustement de specs + un amendement des tickets « prêts à dev ».

3. Décisions transverses à trancher (mêmes pour M1 et M2)

Deux comportements s'appuyaient sur les colonnes inline du tier. À la suppression, il faut choisir leur nouvelle source. Recommandation par défaut entre parenthèses.

  • D1 — Recherche serveur (?search=). Aujourd'hui : fuzzy sur companyName + lastName + email du tier. Après suppression, deux options :
    • (a) restreindre la recherche à companyName seul (simple, mais perte de la recherche par contact) ;
    • (b) [recommandé] étendre la recherche en LEFT JOIN sur la sous-entité contact (first_name / last_name / email du contact), pour préserver l'UX « recherche par nom / contact / email » annoncée dans la barre de recherche.
  • D2 — Colonnes de l'export XLSX (Nom contact / Prénom / Téléphone / Téléphone 2 / Email). Après suppression :
    • (a) supprimer ces colonnes ;
    • (b) [recommandé] les alimenter depuis le contact principal (le contact de plus petit position), pour garder un export utile.

Ces deux décisions sont à valider par le métier (Matthieu) avant implémentation et sont rappelées dans chaque ticket concerné.

4. Fichiers de ce dossier

  • README.md (ce fichier) — décision + découpage.
  • M1-ticket-01-back.md / .prompt.md — description + prompt d'implémentation.
  • M1-ticket-02-front.md / .prompt.md.
  • M1-ticket-03-specs.md / .prompt.md.
  • M2-ticket-specs.md / .prompt.md.
  • M2-amendement-tickets.md — bandeau d'amendement + liste des tickets M2 à mettre à jour.