expria-frontend/docs/adr/003-no-zustand.md

3.3 KiB

ADR 003 — Pas de Zustand pour la V2

Statut : Accepté Date : 2026-04-17 Décideur : Hermann


Contexte

Question posée : faut-il introduire un store global (Zustand, Jotai, Redux Toolkit) dès le scaffold du frontend, en prévision de la complexité future du produit ?

Arguments en faveur d'une intégration précoce :

  • La T2 Live a une state machine complexe (idle → connecting → listening → speaking → processing → ended/error).
  • Plusieurs composants pourraient devoir lire le plan utilisateur actuel.
  • Un produit "scalable" justifierait une gestion d'état "moderne".

Options envisagées

Option A — Zustand dès le départ

  • Avantages : prêt le jour où on en aura besoin, un seul endroit pour l'état global.
  • Inconvénients : dépendance supplémentaire à maintenir, code plus abstrait pour des cas qui ne la nécessitent pas, risque que les devs "poussent" de l'état dans le store par réflexe même quand useState suffit.

Option B — Pas de store global, stratégie en trois couches

  • État serveur → TanStack Query (cache, refetch, invalidation après webhook Stripe).

  • État T2 LiveuseReducer local avec une state machine explicite, dans features/t2-live/hooks/useT2LiveSession.ts.

  • État UI localuseState / useContext pour les cas simples (ex : ouverture d'une modal).

  • Avantages : zéro dépendance supplémentaire, chaque composant gère son propre état, TanStack Query couvre 90% des besoins (tout ce qui vient du serveur).

  • Inconvénients : si plusieurs composants non-parents ont besoin de partager un état client complexe (non-serveur), il faudra passer par React Context ou migrer vers Zustand à ce moment-là.

Décision

Option B — pas de store global pour la V2.

Règle d'introduction future : Zustand (ou équivalent) ne sera introduit que si un cas concret apparaît où plusieurs composants non-parents partagent un état client complexe qui ne peut pas être géré par TanStack Query ni par un Context React local. Jusque là, on s'en passe.

Conséquences

Positives :

  • Une dépendance en moins dans package.json.
  • Un nouveau dev ne se demande pas "pourquoi Zustand pour un produit aussi simple ?".
  • Évite le piège classique : dès qu'un store global existe, les devs y poussent tout, y compris ce qui devrait rester local. Le résultat est un store-spaghetti.
  • TanStack Query gère déjà la synchronisation serveur → UI, ce qui couvre le plan utilisateur, les productions, les rapports, l'historique.

Négatives :

  • Si un besoin complexe de partage d'état client apparaît tôt, il faudra migrer. Mitigation : TanStack Query + Context suffisent dans 95% des cas prévisibles.

À revisiter si :

  • Un composant du header doit réagir en temps réel à un événement du composant de simulation (sans passer par le serveur).
  • La state machine T2 Live devient partagée entre plusieurs écrans (peu probable).
  • L'application a plus de 10 écrans avec de l'état client partagé complexe.

Dans ces cas, introduire Zustand sera une session dédiée avec migration progressive — pas une réécriture.

Références

  • ADR 002 (API client découplé)
  • TanStack Query docs — stratégie de cache
  • ARCHITECTURE.md §4 (structure features/ + shared/)