- aliases.sh : détection par uname au lieu de tester l'existence du dossier
- _AI_INSTRUCTIONS.md : placeholder {{LEADTECH}} pour tous les chemins
- sync-ai-instructions.sh : substitution {{LEADTECH}} → REPO_ROOT à la génération
- .gitignore : exclure CLAUDE.md et AGENTS.md (fichiers générés, machine-spécifiques)
10 KiB
Capitalisation en attente — Lead_tech
Ce fichier sert de zone tampon de capitalisation.
Les agents et les projets peuvent y déposer des propositions
d'amélioration de la base de connaissance globale (Lead_tech).
Le contenu de ce fichier n'est pas encore validé.
Une fois relues et confirmées, les propositions doivent être déplacées vers les fichiers appropriés :
knowledge/backend/patterns/<thème>.mdknowledge/backend/risques/<thème>.mdknowledge/frontend/patterns/<thème>.mdknowledge/frontend/risques/<thème>.mdknowledge/ux/patterns/<thème>.mdknowledge/ux/risques/<thème>.mdknowledge/n8n/patterns/general.mdknowledge/n8n/risques/general.mdknowledge/product/patterns/general.mdknowledge/product/risques/<thème>.mdknowledge/workflow/risques/story-tracking.md10_conventions_redaction.md40_decisions_et_archi.md90_debug_et_postmortem.md
Ce fichier ne doit donc jamais devenir une documentation permanente.
2026-03-25 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/react-native.md
Pourquoi :
Bug récurrent détecté lors du theming : les imports non utilisés (fontWeight) ne génèrent pas d'erreur TypeScript dans React Native, car le type fontWeight est une string — ils passent silencieusement au lint et dans les tests. À signaler comme zone à surveiller lors de toute migration de tokens.
Proposition :
Imports morts de tokens dans les composants UI (React Native)
Lors d'une migration de design system, les imports de tokens abandonnés (ex: fontWeight après passage aux fontes nommées par variante) ne génèrent pas d'erreur TypeScript car le type est compatible avec les usages implicites. Vérifier systématiquement les imports non utilisés avec eslint @typescript-eslint/no-unused-vars ou no-unused-imports activé dans la config ESLint mobile.
2026-03-25 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/expo-router.md
Pourquoi :
Anti-pattern découvert lors de la review theming-1 : labels et routes des tabs inversés sans erreur visible à la compilation. Le tab "Communauté" routait vers explore.tsx (boilerplate) au lieu de community.tsx. Aucun test ne couvrait ce mapping.
Proposition :
Vérifier le mapping name/label des Tabs Expo Router
Dans Expo Router, <Tabs.Screen name="x"> correspond au fichier app/(tabs)/x.tsx. Les labels (title) sont indépendants du routage — un label "Communauté" sur name="explore" affichera explore.tsx sans aucune erreur. Lors d'un refacto de navigation (ajout/renommage de tabs), valider visuellement que chaque label correspond bien à l'écran attendu. Ajouter un test de smoke ou de snapshot de la nav si possible.
2026-03-25 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/react-native.md
Pourquoi :
Input focus ring (border au focus) non implémenté malgré la tâche marquée [x]. React Native ne propose pas de :focus CSS — il faut gérer onFocus/onBlur manuellement avec un state local. Ce pattern est souvent oublié ou marqué done à tort.
Proposition :
Focus ring sur TextInput React Native
React Native n'a pas de pseudo-classe :focus. Pour implémenter un focus ring sur un TextInput, il faut :
const [focused, setFocused] = useState(false)onFocus={() => setFocused(true)}/onBlur={() => setFocused(false)}sur leTextInput- Appliquer un style conditionnel sur le container :
[styles.container, focused && styles.containerFocused]
Ne jamais marquer cette tâche [x] sans avoir vérifié la présence du state focused et des handlers.
2026-03-25 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/react-native.md
Pourquoi : Dette repérée sur login.tsx : écran en anglais alors que tout le reste du flux auth est en français. Aucune erreur de build ou de lint — passe complètement inaperçu jusqu'au test manuel.
Proposition :
Cohérence de langue dans les écrans auth (React Native / Expo Router)
Les textes UI en dur ne sont pas vérifiés par TypeScript ni par les tests unitaires. Une dette de localisation (anglais vs français) peut s'accumuler silencieusement écran par écran. Points de vigilance :
- Vérifier chaque nouvel écran auth lors de la code review : titres, labels de boutons, messages d'erreur, placeholders
- Les tests de snapshot Storybook ou les reviews visuelles sont le seul filet pour ce type de dette
- Prioriser la correction avant la mise en prod (expérience utilisateur incohérente)
2026-03-25 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/expo-router.md
Pourquoi :
Anti-pattern découvert en review 5.1b : router.push('/(auth)/forgot-password') depuis un tab (tabs)/ — navigation cross-groupe avec préfixe de groupe explicite. Peut échouer selon la version d'Expo Router. Le reste du projet utilise /forgot-password sans préfixe de groupe.
Proposition :
Navigation cross-groupe Expo Router — ne jamais préfixer avec le groupe dans router.push
Depuis un écran dans (tabs)/, utiliser router.push('/(auth)/forgot-password') peut échouer silencieusement ou lever une erreur selon la version d'Expo Router, car la résolution des groupes de routes se fait par contexte de navigation. Toujours utiliser le chemin sans groupe explicite : router.push('/forgot-password' as never). Les groupes (auth), (tabs) etc. sont des conventions d'organisation de fichiers, pas des segments de route réels.
2026-03-25 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/react-native.md
Pourquoi :
Pattern contentInset iOS-only trouvé dans deux écrans (settings.tsx, profile.tsx déjà existant) — aucune erreur au build, invisible sur iOS, cassé sur Android (contenu sous la tab bar).
Proposition :
contentInset est iOS-only sur ScrollView React Native
ScrollView.contentInset n'est pas supporté sur Android. Pour gérer le padding bottom autour d'une bottom tab bar, utiliser contentContainerStyle={{ paddingBottom: insets.bottom }} à la place. Pattern à auditer systématiquement lors de la review de tout nouvel écran avec ScrollView + bottom navigation.
2026-03-27 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/react-native.md
Pourquoi :
Anti-pattern récurrent dans les stores Zustand mobile : le catch d'une erreur throwée depuis apiRequest (qui throw un objet JSON, pas une Error) ne donne pas de message lisible si on fait err instanceof Error uniquement. Détecté lors de la review 5.2.
Proposition :
Catch Zustand store — objet throwé vs Error
Quand apiRequest propage une erreur HTTP en throwant le JSON brut { error: { code, message } }, le catch Zustand ne peut pas se limiter à err instanceof Error. Le pattern robuste :
catch (err: unknown) {
let message = 'Erreur de connexion au serveur.';
if (err instanceof Error) {
message = err.message;
} else if (
typeof err === 'object' && err !== null &&
'error' in err &&
typeof (err as { error: { message?: string } }).error?.message === 'string'
) {
message = (err as { error: { message: string } }).error.message;
}
set({ error: message, isLoading: false });
}
Appliquer ce pattern dans tous les stores qui appellent apiRequest directement.
2026-03-27 — app-alexandrie
FILE_UPDATE_PROPOSAL Fichier cible : knowledge/frontend/risques/react-native.md
Pourquoi :
apiRequest (http-client.ts) ne vérifiait pas response.ok — retournait le JSON brut même sur 404/500. Erreur non throwée → res.error dépendait du format de l'API NestJS. En cas de réponse non-JSON (proxy 502 HTML), response.json() throwait une SyntaxError cryptique. Détecté review 5.2.
Proposition :
fetch sans vérification response.ok — toujours throw sur non-2xx
Après tout fetch(), toujours vérifier response.ok avant de retourner le JSON :
const json = (await response.json()) as T;
if (!response.ok) {
throw json; // throw le body d'erreur structuré
}
return json;
Sans ce check, les erreurs 404/500 passent silencieusement si le service appelant ne vérifie que le body. Risque accru avec les proxies qui retournent du HTML sur erreur.
Format attendu
Chaque proposition doit suivre ce format :
DATE — PROJET
FILE_UPDATE_PROPOSAL
Fichier cible : <knowledge/backend/patterns/<thème>.md | knowledge/backend/risques/<thème>.md | knowledge/frontend/patterns/<thème>.md | knowledge/frontend/risques/<thème>.md | knowledge/ux/patterns/<thème>.md | knowledge/ux/risques/<thème>.md | knowledge/n8n/patterns/general.md | knowledge/n8n/risques/general.md | knowledge/product/patterns/general.md | knowledge/product/risques/<thème>.md | knowledge/workflow/risques/story-tracking.md | 10_conventions_redaction.md | 40_decisions_et_archi.md | 90_debug_et_postmortem.md>
Pourquoi :
<raison pour laquelle ce savoir mérite d'être capitalisé>
Proposition :
<contenu suggéré à intégrer dans le fichier cible>
Exemple
2026-03-08 — portfolio
FILE_UPDATE_PROPOSAL
Fichier cible : knowledge/backend/patterns/prisma.md
Pourquoi :
Pattern réutilisable validé sur un projet réel.
Proposition :
## Nom du pattern
Description courte, factuelle, orientée réutilisation.
Règles
- Les agents peuvent proposer librement ici.
- Les propositions doivent rester courtes et factuelles.
- La validation et l'intégration finale dans
Lead_techsont faites manuellement. - Une fois intégrée, la proposition doit être supprimée de ce fichier.
- La structure de ce fichier est restaurée à son état initial (voir
70_templates/template_a_capitaliser.md).
Rôle dans l'architecture
Projet
↓
Proposition
↓
95_a_capitaliser.md
↓
Validation humaine
↓
Lead_tech
Ce mécanisme permet :
- d'éviter la pollution de la base de connaissance
- de capitaliser progressivement l'expérience des projets
- de garder
Lead_techcohérent et fiable.