capitalisation: TOCTOU Prisma (fusion + généralisation), Contracts schema orphelin, Zustand optimistic update sous-listes

- Fusion entrée TOCTOU : étend l'entrée multi-tenant existante avec le cas
  général "idempotence / plafond" (check métier hors transaction) — app-alexandrie story 4.6
- Nouvelle entrée : Contracts schema orphelin / type de retour désynchronisé
  (RequestSchema non importé, type inline au lieu du type contracts)
- Nouvelle entrée : Zustand optimistic update sur item absent de la liste
  principale (fallback sur pinnedThreads / showcasedThreads)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
MaksTinyWorkshop
2026-03-23 20:42:50 +01:00
parent e61e3d5ea8
commit 8f4ac2b033
2 changed files with 104 additions and 8 deletions

View File

@@ -59,6 +59,7 @@ Dernière mise à jour : 23-03-2026
- [`useTransition` global pour des listes d'items interactifs](#risque-usetransition-global-liste-items)
- [`useCallback` inutile quand le callback est wrappé en inline au render](#risque-usecallback-inutile-inline)
- [Formulaire React avec `defaultValue` sans `key` prop](#risque-formulaire-defaultvalue-sans-key)
- [Zustand : optimistic update sur item absent de la liste principale](#risque-zustand-optimistic-update-sous-listes)
---
@@ -1010,3 +1011,37 @@ const handleToggle = useCallback((id: string) => { ... }, []); // stable ✓
- **Règle** : tout formulaire d'édition réutilisé pour plusieurs entités doit avoir une `key` distincte par entité
- Contexte technique : React / Next.js — app-template-resto 21-03-2026
---
<a id="risque-zustand-optimistic-update-sous-listes"></a>
## Zustand : optimistic update sur item absent de la liste principale
### Risques
- Une action admin qui cherche l'item uniquement dans `state.threads` (liste paginée principale) manque les items présents exclusivement dans `state.pinnedThreads` ou `state.showcasedThreads`
- L'optimistic update ne se reflète pas visuellement même si l'appel API a réussi
### Symptômes
- L'item mis à jour par une action admin n'apparaît pas dans la nouvelle sous-liste après l'action
- Bug reproductible uniquement quand l'item est épinglé / en vitrine mais pas dans la page courante du flux principal
### Bonnes pratiques / mitigations
```typescript
// ❌ Anti-pattern : cherche uniquement dans la liste principale paginée
const target = state.threads.find((t) => t.id === threadId);
// → manque les items présents uniquement dans pinnedThreads / showcasedThreads
// ✅ Pattern correct : fallback sur toutes les sous-listes du store
const target =
state.threads.find((t) => t.id === threadId) ??
state.pinnedThreads.find((t) => t.id === threadId) ??
state.showcasedThreads.find((t) => t.id === threadId);
```
- **Règle** : toute action qui opère sur un item pouvant être présent dans plusieurs sous-listes doit chercher dans l'ensemble de ces listes
- Règle complémentaire : ne pas mettre à jour une sous-liste (ex: `pinnedThreads`) lors d'une action qui n'y a pas de rapport (ex: mise en vitrine ne touche pas `pinnedThreads`)
- Contexte technique : React Native / Zustand — app-alexandrie 23-03-2026