Files
_Assistant_Lead_Tech/95_a_capitaliser.md
2026-03-10 21:54:34 +01:00

9.3 KiB
Raw Blame History

Capitalisation en attente — Lead_tech

Ce fichier sert de zone tampon de capitalisation.

Les agents et les projets peuvent y déposer des propositions damé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 :

  • 10_backend_patterns_valides.md
  • 10_frontend_patterns_valides.md
  • 10_ux_patterns_valides.md
  • 10_product_patterns_valides.md
  • 10_n8n_patterns_valides.md
  • 10_backend_risques_et_vigilance.md
  • 10_frontend_risques_et_vigilance.md
  • 10_ux_risques_et_vigilance.md
  • 10_n8n_risques_et_vigilance.md
  • 10_conventions_redaction.md
  • 40_decisions_et_archi.md
  • 90_debug_et_postmortem.md

Ce fichier ne doit donc jamais devenir une documentation permanente.


Format attendu

Chaque proposition doit suivre ce format :

DATE — PROJET

FILE_UPDATE_PROPOSAL
Fichier cible : <10_backend_patterns_valides.md | 10_frontend_patterns_valides.md | 10_ux_patterns_valides.md | 10_product_patterns_valides.md | 10_n8n_patterns_valides.md | 10_backend_risques_et_vigilance.md | 10_frontend_risques_et_vigilance.md | 10_ux_risques_et_vigilance.md | 10_n8n_risques_et_vigilance.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 : 10_backend_patterns_valides.md

Pourquoi :
Ordre d'enregistrement des Guards NestJS causant un bug
`request.user undefined` observé à plusieurs reprises.

Proposition :

## Ordre des Guards NestJS

Toujours enregistrer `AuthGuard` avant les Guards dépendants
(`EmailVerifiedGuard`, `RoleGuard`, etc.).

Sinon `request.user` peut être undefined dans les guards suivants.

Règles

  1. Les agents peuvent proposer librement ici.
  2. Les propositions doivent rester courtes et factuelles.
  3. La validation et l'intégration finale dans Lead_tech sont faites manuellement.
  4. Une fois intégrée, la proposition doit être supprimée de ce fichier.
  5. La structure de ce fichier est restaurée à son état initial (voir 70_templates/template_a_capitaliser.md).

2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 10_backend_patterns_valides.md

Pourquoi : Pattern réutilisable pour exposer une progression V1 sans ouvrir trop tôt un domaine achievements ou analytics, tout en gardant une couture propre vers des contributions futures.

Proposition :

Progression V1 calculée sans persistance dédiée

Pour une feature de progression minimum viable :

  • garder l'agrégat dans le domaine métier déjà source de vérité (content, billing, etc.)
  • calculer les compteurs période (thisWeek, thisMonth) côté base avec count/agrégations filtrées
  • centraliser le catalogue d'objectifs en code explicite et testable
  • prévoir une couture zéro-safe pour les sources futures (contributions, posts, etc.) au lieu d'inventer les tables en avance

Évite le scope creep vers un module achievements prématuré et garde un contrat stable.

2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 10_frontend_patterns_valides.md

Pourquoi : Pattern frontend/mobile utile pour brancher un écran récapitulatif serveur sans dupliquer la logique réseau dans l'écran et sans navigation impérative via store.getState().

Proposition :

Écran récapitulatif branché sur store de domaine existant

Quand une vue récapitulative dépend d'un domaine déjà présent :

  • étendre le service et le store existants au lieu de créer un nouveau domaine artificiel
  • laisser l'écran purement déclaratif avec états loading / error / empty / nominal
  • déclencher le chargement via useEffect et actions du store
  • réserver refresh à une action idempotente du store
  • ajouter le point d'entrée depuis l'écran parent naturel (library, profile, etc.) au lieu de refondre la navigation globale

Réduit les régressions et garde le comportement async testable.


2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 10_frontend_patterns_valides.md

Pourquoi : Le pull-to-refresh mobile sur listes paginées a besoin dune vraie idempotence côté store, sinon on crée des doublons et des courses réseau invisibles. Le pattern a été validé ici avec Zustand sans introduire de lib de cache serveur.

Proposition : Pattern "Refresh idempotent sur store de liste paginée" : conserver une promesse de refresh en vol partagée, refuser les refresh concurrents, remplacer atomiquement la liste à la fin du refresh, et dédupliquer les items par identifiant au merge des pages suivantes.


2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 10_frontend_risques_et_vigilance.md

Pourquoi : Un écran gated par des droits distants peut tomber dans un faux état loading infini si lerreur de chargement des entitlements laisse les données à null et relance automatiquement leffet. Le défaut a été détecté en review sur la Bibliothèque mobile.

Proposition : Risque "Loading infini sur écran gated" : si un écran dépend dun store dentitlements ou dautorisations, distinguer explicitement loading, error, ready, et bloquer les retries automatiques en boucle après erreur tant quun retry utilisateur ou une nouvelle condition dentrée na pas eu lieu.

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_tech cohérent et fiable.

2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 10_backend_patterns_valides.md

Pourquoi : Quand une story métier demande un pouvoir interne limité, ajouter un rôle minimal persistant + un guard dédié permet de sécuriser lauthz sans ouvrir prématurément un RBAC complet. Le pattern a été validé ici pour la publication admin de contenus.

Proposition : Pattern "Autorisation interne minimale sans RBAC complet" : introduire un enum de rôle simple côté source de vérité backend (ex. USER | ADMIN), le propager dans la session/auth, puis créer un décorateur + guard dédiés à la capacité sensible. Éviter les booléens front, les emails hardcodés et les if dispersés dans les contrôleurs.


2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 10_frontend_patterns_valides.md

Pourquoi : Pour une capacité admin mince sur mobile, une route dédiée légère branchée sur le domaine existant et un refresh explicite du store après mutation permettent de rester testable et robuste sans lancer un back-office séparé.

Proposition : Pattern "UI admin légère sur domaine existant" : pour une action interne simple (publication, activation, modération légère), ajouter une route dédiée minimale qui réutilise le service/store métier existant, afficher le statut courant, bloquer les actions concurrentes avec un flag isUpdating*, et déclencher un refresh explicite des vues impactées après succès au lieu dun fire-and-forget.


2026-03-10 — app-alexandrie

FILE_UPDATE_PROPOSAL Fichier cible : 90_debug_et_postmortem.md

Pourquoi : tsx (esbuild) ignore emitDecoratorMetadata — l'injection par type NestJS est silencieusement undefined au runtime, même avec emitDecoratorMetadata: true dans tsconfig.json. Bug difficile à diagnostiquer car aucune erreur de compilation.

Proposition :

tsx + NestJS : injection par type cassée silencieusement

Contexte : app-alexandrie, Epic 3, 2026-03-10

Symptôme : TypeError: Cannot read properties of undefined (reading 'get') dans le constructeur d'un service NestJS. this.config (de type ConfigService) est undefined malgré @Injectable() et ConfigModule correctement configuré.

Cause racine : tsx utilise esbuild pour transpiler TypeScript. esbuild ignore emitDecoratorMetadata même si activé dans tsconfig. NestJS ne peut donc pas résoudre les types pour l'injection de dépendances par type (constructor(private config: ConfigService)).

Conditions : runner = tsx watch, module: nodenext dans tsconfig (requis pour Prisma v7 ESM), emitDecoratorMetadata: true présent mais ignoré.

Fix : Remplacer l'injection ConfigService par process.env['VAR'] directement dans le constructeur. ConfigModule.forRoot avec isGlobal: true charge dotenv en amont → process.env est peuplé avant l'instanciation des services.

// AVANT (cassé avec tsx)
constructor(private readonly config: ConfigService) {
  const host = this.config.get('REDIS_HOST');
}

// APRÈS (compatible tsx)
constructor() {
  const host = process.env['REDIS_HOST'] ?? 'localhost';
}

Alternative non retenue : nest start --watch → conflits ESM/CJS avec Prisma v7 + module: nodenext (exports is not defined).

Règle : Dans un projet NestJS avec tsx comme runner, ne jamais injecter ConfigService par type. Toujours utiliser process.env directement dans les services d'infra (Redis, DB pools, etc.).