mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
Purge _ A capitaliser
This commit is contained in:
@@ -7,7 +7,7 @@ Ce fichier recense des risques front-end susceptibles de provoquer :
|
||||
- dette technique rapide,
|
||||
- régressions UX/perf/a11y.
|
||||
|
||||
Dernière mise à jour : 12-03-2026
|
||||
Dernière mise à jour : 20-03-2026
|
||||
|
||||
---
|
||||
|
||||
@@ -33,6 +33,12 @@ Dernière mise à jour : 12-03-2026
|
||||
- [Auto-reset d’un état dégradé sur toute réponse 2xx](#risque-auto-reset-etat-degrade)
|
||||
- [Refresh store en fire-and-forget après mutation](#risque-refresh-store-fire-and-forget)
|
||||
- [Loading infini sur écran gated par droits distants](#risque-loading-infini-ecran-gated)
|
||||
- [Jest React Native — config node bloque les composants `.tsx`](#risque-jest-rn-config-node)
|
||||
- [Bouton OAuth présent mais handler vide après refacto UI](#risque-oauth-handler-vide)
|
||||
- [Double système d'espacement dans un monorepo Expo](#risque-double-systeme-espacement)
|
||||
- [Dimensions d'image via tokens `spacing` (React Native)](#risque-dimensions-image-via-spacing)
|
||||
- [Écran détail Expo Router — store vide en deep link / reload](#risque-store-vide-deep-link)
|
||||
- [`useEffect` fetch — guard incomplet sur les états terminaux](#risque-useeffect-guard-incomplet)
|
||||
|
||||
---
|
||||
|
||||
@@ -281,3 +287,156 @@ Dernière mise à jour : 12-03-2026
|
||||
- Bloquer les retries automatiques en boucle après erreur
|
||||
- Réautoriser un retry seulement via action utilisateur explicite ou nouvelle condition d’entrée
|
||||
- Contexte technique : React Native / Expo / store d’entitlements — 10-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-jest-rn-config-node"></a>
|
||||
## Jest React Native — config node bloque les composants `.tsx`
|
||||
|
||||
### Risques
|
||||
|
||||
- `SyntaxError: Cannot use import statement outside a module` lors de l’import d’un barrel `.ts` qui réexporte des `.tsx`
|
||||
- Impossible d’importer des composants React Native dans les tests — JSX non transformé
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Erreur de syntaxe inattendue au run des tests sur un fichier `.ts` qui importe un `.tsx`
|
||||
- Les tests de tokens passent mais tout test touchant un composant échoue
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- `transform: { ‘^.+\\.ts$’: ‘ts-jest’ }` ne transforme que `.ts` — pas `.tsx`
|
||||
- **Pattern recommandé** : tester la logique pure (tokens, valeurs de style) dans `.spec.ts`, le rendu visuel dans `.spec.tsx` avec une config séparée (`@testing-library/react-native` + `babel-jest`)
|
||||
- Exporter le `StyleSheet` de chaque composant pour le tester sans JSX (voir pattern dédié dans `10_frontend_patterns_valides.md`)
|
||||
- Contexte technique : React Native / Jest / ts-jest — app-alexandrie 19-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-oauth-handler-vide"></a>
|
||||
## Bouton OAuth présent mais handler vide après refacto UI
|
||||
|
||||
### Risques
|
||||
|
||||
- L’OAuth est silencieusement cassé sur le nouvel écran — zéro erreur au démarrage, zéro crash
|
||||
- L’AC "toutes les fonctionnalités préservées" peut être coché alors que le bouton est mort
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `<Button title="Google" onPress={() => {}} />` — handler vide après copie depuis un ancien écran
|
||||
- OAuth fonctionnel sur l’écran précédent (`welcome.tsx`) mais absent sur le nouvel écran refactorisé
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Toute refacto UI qui introduit un bouton OAuth doit brancher le hook existant (`useGoogleAuth(onSuccess)`)
|
||||
- Si la story exclut explicitement la fonctionnalité : soit le bouton n’apparaît pas, soit `disabled` avec un label explicite ("bientôt disponible")
|
||||
- **Checklist review** : chercher `onPress={() => {}}` sur tous les boutons OAuth dans les écrans refactorisés
|
||||
- Contexte technique : Expo Router / React Native — app-alexandrie story 0.3, 19-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-double-systeme-espacement"></a>
|
||||
## Double système d’espacement dans un monorepo Expo
|
||||
|
||||
### Risques
|
||||
|
||||
- Deux échelles d’espacement coexistent avec des noms différents pour des valeurs identiques (`Spacing.three = 16` vs `spacing.base = 16`)
|
||||
- L’audit "zéro hardcode" ne détecte pas l’inconsistance car les deux sont des constantes nommées
|
||||
- Les deux échelles peuvent diverger silencieusement
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `import { Spacing } from ‘@/constants/theme’` coexiste avec `import { spacing } from ‘@/theme’`
|
||||
- Certains screens refactorisés utilisent l’ancien système sans que personne ne le détecte
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Dès la création de `src/theme/spacing.ts`, supprimer ou vider `constants/theme.ts` (sauf constantes vraiment spécifiques : `MaxContentWidth`, `BottomTabInset`)
|
||||
- Faire un `grep from ‘@/constants/theme’` à chaque story pour détecter les usages résiduels
|
||||
- **Cause racine** : le template Expo génère `constants/theme.ts` avec `Spacing = { one, two, three... }` — à purger explicitement lors de la story design tokens
|
||||
- Contexte technique : Expo / React Native — app-alexandrie story 0.5, 19-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-dimensions-image-via-spacing"></a>
|
||||
## Dimensions d’image via tokens `spacing` (React Native)
|
||||
|
||||
### Risques
|
||||
|
||||
- Si `spacing.huge` change pour une raison d’espacement, la taille de l’image change silencieusement
|
||||
- Régression visuelle sans que personne ne réalise l’impact — les deux changements semblent indépendants
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `width: spacing.huge, height: spacing.huge` pour une image dont la taille est fixée par la spec Figma
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
// Correct : constante locale ou token dédié
|
||||
const THUMBNAIL_SIZE = 48; // Figma spec node 1-16147
|
||||
|
||||
// OU token dans un fichier sizes.ts dédié si la valeur est partagée
|
||||
export const sizes = { thumbnail: 48, avatar: 40 } as const;
|
||||
```
|
||||
|
||||
**Règle** : `spacing` = espacement entre éléments. `sizes` ou constantes locales = dimensions de composants.
|
||||
|
||||
- Contexte technique : React Native / design tokens — app-alexandrie story 0.4, 19-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-store-vide-deep-link"></a>
|
||||
## Écran détail Expo Router — store vide en deep link / reload
|
||||
|
||||
### Risques
|
||||
|
||||
- L’écran détail (`[slug].tsx`) lit ses données depuis un store Zustand peuplé par l’écran liste
|
||||
- En deep link, kill + reopen ou navigation OS back, le store est vide → "introuvable" affiché à tort
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Écran détail vide ou erreur "non trouvé" sur accès direct (pas via la liste)
|
||||
- Fonctionne normalement en navigation standard mais échoue sur reload
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
// useEffect de secours dans l’écran détail
|
||||
useEffect(() => {
|
||||
if (!accessToken) return;
|
||||
if (items.length > 0 || isLoading || errorState) return;
|
||||
void fetchItems(accessToken);
|
||||
}, [accessToken, items.length, isLoading, errorState, fetchItems]);
|
||||
```
|
||||
|
||||
- Ne pas afficher "introuvable" avant d’avoir vérifié que le store a bien été peuplé
|
||||
- Contexte technique : Expo Router / Zustand — app-alexandrie story 4.1, 20-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-useeffect-guard-incomplet"></a>
|
||||
## `useEffect` fetch — guard incomplet sur les états terminaux
|
||||
|
||||
### Risques
|
||||
|
||||
- Si l’état "zéro résultat intentionnel" (ex : `paywallRequired`) n’est pas dans les conditions de court-circuit, le fetch est re-déclenché à chaque re-render ou focus
|
||||
- Boucle de fetch infini sur un état métier normal
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `forums.length === 0` et `isLoading === false` → le guard ne court-circuite pas → fetch re-déclenché en boucle
|
||||
- Visible en focus sur l’écran depuis un autre onglet
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
// ❌ Pattern à risque — re-fetch si paywallRequired (forums vide + isLoading false)
|
||||
if (forums.length > 0 || isLoading) return;
|
||||
|
||||
// ✅ Pattern correct — court-circuit sur l’état terminal
|
||||
if (forums.length > 0 || isLoading || paywallRequired) return;
|
||||
```
|
||||
|
||||
**Règle** : les états "zéro résultat intentionnel" (liste vide + flag métier) doivent être traités comme "données présentes" dans le guard de fetch.
|
||||
|
||||
- Contexte technique : React Native / Zustand / Expo Router — app-alexandrie story 4.1, 20-03-2026
|
||||
|
||||
Reference in New Issue
Block a user