mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 13:31:43 +02:00
capitalisation: intégrer 12 entrées depuis app-alexandrie et app-template-resto
- backend/risques/nestjs : guard multi-statut READ_METHODS avant statut - backend/patterns/nestjs : fusionner lastSeenAt dans la réconciliation - backend/risques/contracts : pas de process.env dans services/helpers - backend/risques/nextjs : self-request Server Action + EXDEV atomic write - backend/risques/prisma : champ enum-like stocké en String - frontend/risques/general : Alert.prompt iOS-only - frontend/risques/tests : 3 anti-patterns (helpers copiés, test indirect, test façade) - workflow/risques/story-tracking : 2 entrées (hors périmètre, File List approximative) - skill capitalisation-triage : nouveau format de rapport (tableaux par domaine) - 95_a_capitaliser.md : purgé
This commit is contained in:
@@ -102,69 +102,3 @@ 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-30 — app-alexandrie
|
||||
|
||||
FILE_UPDATE_PROPOSAL
|
||||
Fichier cible : knowledge/backend/risques/nestjs.md
|
||||
|
||||
Pourquoi :
|
||||
Guard NestJS avec statuts multiples (PENDING/BLOCKED) : le check READ_METHODS doit précéder les checks de statut. Sans ça, les sessions BLOCKED ne peuvent pas accéder aux endpoints GET (ex: /auth/devices), enfermant l'utilisateur sans possibilité de révocation.
|
||||
|
||||
Proposition :
|
||||
### Guard multi-statut : READ_METHODS avant statut, whitelist pour les endpoints de sortie de blocage
|
||||
|
||||
**Risque** : un guard qui vérifie le statut BLOCKED avant de vérifier la méthode en lecture bloque les GET, dont les endpoints permettant à l'utilisateur de sortir du blocage (lister ses appareils, révoquer).
|
||||
|
||||
**Règle** :
|
||||
1. Toujours vérifier `READ_METHODS.has(request.method)` EN PREMIER, avant tout check de statut.
|
||||
2. Définir une whitelist explicite des writes autorisés même en état bloqué (ex: révocation). Sans elle, le circuit de sortie est fermé.
|
||||
|
||||
```typescript
|
||||
// ❌ DANGEREUX — BLOCKED bloque aussi les GET
|
||||
if (user.sessionStatus === 'BLOCKED') throw new HttpException(...);
|
||||
if (READ_METHODS.has(request.method)) return true; // jamais atteint pour BLOCKED
|
||||
|
||||
// ✅ CORRECT
|
||||
if (READ_METHODS.has(request.method)) return true;
|
||||
if (isDeviceManagementPath(request.path)) return true; // whitelist writes critiques
|
||||
if (user.sessionStatus === 'BLOCKED') throw new HttpException(...);
|
||||
```
|
||||
|
||||
FILE_UPDATE_PROPOSAL
|
||||
Fichier cible : knowledge/backend/patterns/nestjs.md
|
||||
|
||||
Pourquoi :
|
||||
Pattern fusion DB : quand un service de réconciliation d'état est appelé à chaque requête authentifiée, faire 2 prisma.update séparés (statut + lastSeenAt) double le coût DB par requête.
|
||||
|
||||
Proposition :
|
||||
### Fusionner lastSeenAt dans l'update de réconciliation — évite N requêtes DB par request
|
||||
|
||||
Passer `now` en paramètre et inclure `lastSeenAt` dans le même update conditionnel.
|
||||
|
||||
```typescript
|
||||
// ❌ 2 requêtes par requête authentifiée
|
||||
private async reconcileSessionStatus(session) {
|
||||
if (statusChanged) await prisma.session.update({ data: { status, graceEndsAt } });
|
||||
}
|
||||
await prisma.session.update({ data: { lastSeenAt: now } }); // 2ème update systématique
|
||||
|
||||
// ✅ 1 requête — lastSeenAt toujours inclus dans le même appel
|
||||
private async reconcileSessionStatus(session, now = new Date()) {
|
||||
await prisma.session.update({
|
||||
data: { lastSeenAt: now, ...(statusChanged && { status, graceEndsAt }) }
|
||||
});
|
||||
}
|
||||
```
|
||||
2026-03-30 — base / FILE_UPDATE_PROPOSAL / Fichier cible: knowledge/backend/risques/contracts.md / Pourquoi: Une story marquée conforme « pas de process.env direct en service métier » dérivait encore vers une lecture brute de variable d'environnement dans un helper utilisé par le service; la validation Zod existait mais était contournée au runtime. / Proposition: Ajouter une vigilance explicite « Feature flags backend: ne pas lire process.env dans les services ni helpers métier; injecter ConfigService (ou config validée) et centraliser la lecture via une fonction pure recevant la config injectée. » + symptôme review « tests green mais dépendance implicite à l'état process global ».
|
||||
|
||||
2026-03-30 — base / FILE_UPDATE_PROPOSAL / Fichier cible: knowledge/frontend/risques/tests.md / Pourquoi: Un test déclaré comme “test composant” validait en réalité des helpers recopiés dans le fichier de test, créant un faux positif (la logique réellement exécutée en production pouvait diverger sans casser le test). / Proposition: Ajouter un anti-pattern « Helpers copiés localement dans les tests » avec règle: les tests doivent importer le module réellement utilisé par l'écran/composant (ou extraire un utilitaire partagé), jamais dupliquer la logique métier dans le test. Inclure checklist review: « aucune fonction de prod recopiée dans *.spec.ts ».
|
||||
2026-03-30 — base / FILE_UPDATE_PROPOSAL / Fichier cible: knowledge/workflow/risques/story-tracking.md / Pourquoi: En code review, une story peut afficher des tâches [x] et une File List propre, mais le working tree contient de nombreux changements source non tracés pour cette story; sans note de périmètre explicite, le reviewer peut valider un faux scope ou rejeter à tort. / Proposition: Ajouter une règle « File List vs branch dirty »: si des changements hors story sont présents, documenter explicitement un bloc “hors périmètre de la story” dans le Dev Agent Record (liste courte + justification), et ne marquer done qu'après clarification de périmètre.
|
||||
|
||||
2026-03-30 — base / FILE_UPDATE_PROPOSAL / Fichier cible: knowledge/frontend/risques/tests.md / Pourquoi: Un test “écran” qui importe seulement un helper utilitaire ne valide pas le comportement réel de l'écran; il peut rester vert même si la logique de décision UI dans le screen diverge. / Proposition: Ajouter un anti-pattern « test écran indirect »: imposer que la logique de décision UI soit soit testée via rendu composant, soit extraite dans un module dédié importé par le screen et par le test (single source of truth), jamais testée uniquement via un helper adjacent non relié au flux écran.
|
||||
|
||||
2026-03-31 — app-template-resto / FILE_UPDATE_PROPOSAL / Fichier cible: knowledge/backend/risques/nextjs.md / Pourquoi: En code review story 4.1, une Server Action appelait fetch() vers elle-même (loopback HTTP) pour contourner la contrainte “server-only”. Cette approche ajoute une latence réseau, une fragilité sur APP_URL en Docker, une double authentification, et une surface SSRF. La vraie solution est d'appeler directement la fonction server-only depuis la Server Action — les deux sont côté serveur et le “server-only” ne bloque pas les imports inter-modules serveur. / Proposition: Ajouter un anti-pattern « Self-request / loopback HTTP depuis Server Action »: une Server Action peut importer et appeler directement des modules marqués server-only sans fetch interne. Règle: si tu te retrouves à reconstituer des cookies de session pour faire un fetch vers ta propre API depuis une Server Action, c'est un signal que l'appel doit être direct.
|
||||
|
||||
2026-03-31 — app-template-resto / FILE_UPDATE_PROPOSAL / Fichier cible: knowledge/backend/risques/nextjs.md / Pourquoi: L'écriture atomique (tmp + rename) pour les fichiers media échoue avec EXDEV si le tmpdir système (/tmp) est sur un device différent du volume de stockage (cas courant Docker bind-mount). / Proposition: Ajouter un pattern « écriture atomique intra-device »: créer le fichier temporaire dans le même répertoire que la destination finale (pas dans os.tmpdir()), ce qui garantit que rename() reste intra-device et ne lève jamais EXDEV. Inclure note: s'assurer que le répertoire cible est créé avant l'écriture du tmp.
|
||||
|
||||
@@ -50,5 +50,5 @@
|
||||
# - automatiser certains audits inter-projets
|
||||
#
|
||||
# Les lignes commençant par # sont ignorées.
|
||||
app-alexandrie|NestJS + Expo (React Native) + Prisma + pnpm monorepo|mindleaf|Epic 7 en cours
|
||||
app-alexandrie|NestJS + Expo (React Native) + Prisma + pnpm monorepo|mindleaf|Epic 8 en cours
|
||||
app-template-resto|Next.js Prisma+PostgreSQL|perso|Epic 4 en cours
|
||||
|
||||
@@ -136,3 +136,32 @@ if (count !== null && count > QUOTA_MAX) {
|
||||
- [ ] Mode dégradé permissif si `count === null` (Redis down)
|
||||
- [ ] Clé nommée `{app}:quota:{action}:{userId}:{yyyy-mm-dd}` (date UTC)
|
||||
- [ ] Anti-pattern évité : `incrBy` + `setEx` séparés (race condition si count === 1 concurrent)
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-fusionner-lastseenat-reconciliation"></a>
|
||||
## Pattern : Fusionner `lastSeenAt` dans l'update de réconciliation — évite N requêtes DB par requête
|
||||
|
||||
- Objectif : éviter deux appels Prisma distincts (réconciliation + lastSeenAt) sur chaque requête authentifiée.
|
||||
- Contexte : service de réconciliation d'état de session appelé à chaque request via guard ou middleware.
|
||||
- Quand l'utiliser : dès qu'un `lastSeenAt` est mis à jour systématiquement et qu'un update conditionnel coexiste.
|
||||
- Avantage : 1 requête DB par requête authentifiée au lieu de 2.
|
||||
- Validé le : 30-03-2026
|
||||
- Contexte technique : NestJS / Prisma — app-alexandrie
|
||||
|
||||
### Implémentation (exemple minimal)
|
||||
|
||||
```typescript
|
||||
// ❌ 2 requêtes par requête authentifiée
|
||||
private async reconcileSessionStatus(session) {
|
||||
if (statusChanged) await prisma.session.update({ data: { status, graceEndsAt } });
|
||||
}
|
||||
await prisma.session.update({ data: { lastSeenAt: now } }); // 2ème update systématique
|
||||
|
||||
// ✅ 1 requête — lastSeenAt toujours inclus dans le même appel
|
||||
private async reconcileSessionStatus(session, now = new Date()) {
|
||||
await prisma.session.update({
|
||||
data: { lastSeenAt: now, ...(statusChanged && { status, graceEndsAt }) }
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
@@ -163,3 +163,27 @@ Tableau de correspondance :
|
||||
|
||||
- **Règle** : HTTP 403 = "tu n'as pas le droit d'effectuer cette action". HTTP 400 = "ta requête est mal formée".
|
||||
- Contexte technique : NestJS / HTTP — 20-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-process-env-direct-service"></a>
|
||||
## Feature flags / config : lecture directe de `process.env` dans les services ou helpers métier
|
||||
|
||||
### Risques
|
||||
|
||||
- Tests verts malgré une dépendance implicite à l'état global du process
|
||||
- La validation Zod de l'env (ConfigService) existe mais est contournée au runtime via un helper non injecté
|
||||
- Story conforme "pas de process.env direct en service métier" mais violation dans un helper utilisé par le service
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `process.env.FEATURE_FLAG_X` dans un helper métier plutôt que dans un module ConfigService
|
||||
- Tests passent mais comportement diverge selon l'env du process
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Ne jamais lire `process.env` directement dans les services ni les helpers métier.
|
||||
- Injecter `ConfigService` (NestJS) et centraliser la lecture via une fonction pure recevant la config injectée.
|
||||
- **Checklist review** : rechercher `process.env` dans `src/` hors `config/` ou `main.ts` — tout hit est suspect.
|
||||
|
||||
- Contexte technique : NestJS / ConfigService — 30-03-2026
|
||||
|
||||
@@ -100,3 +100,36 @@ throw new HttpException(
|
||||
- Interdire les méthodes "cachées" consommées hors contrat
|
||||
- Tester au moins une implémentation par le contrat abstrait
|
||||
- Contexte technique : TypeScript / provider strategy — 10-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-guard-multistatut-read-methods"></a>
|
||||
## Guard multi-statut : ordre READ_METHODS avant statut et whitelist des writes critiques
|
||||
|
||||
### Risques
|
||||
|
||||
- Un guard qui vérifie le statut BLOCKED avant la méthode HTTP bloque aussi les GET, enfermant l'utilisateur sans moyen de sortir (ex : révoquer un appareil).
|
||||
- Sans whitelist explicite des writes autorisés en état bloqué, le circuit de sortie est fermé.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- L'utilisateur avec `sessionStatus === 'BLOCKED'` ne peut pas accéder à `GET /auth/devices`
|
||||
- Tests passent mais l'ordre des conditions est inversé
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
```typescript
|
||||
// ❌ DANGEREUX — BLOCKED bloque aussi les GET
|
||||
if (user.sessionStatus === 'BLOCKED') throw new HttpException(...);
|
||||
if (READ_METHODS.has(request.method)) return true; // jamais atteint pour BLOCKED
|
||||
|
||||
// ✅ CORRECT
|
||||
if (READ_METHODS.has(request.method)) return true;
|
||||
if (isDeviceManagementPath(request.path)) return true; // whitelist writes critiques
|
||||
if (user.sessionStatus === 'BLOCKED') throw new HttpException(...);
|
||||
```
|
||||
|
||||
- **Règle** : dans tout guard multi-statut, vérifier `READ_METHODS.has(request.method)` EN PREMIER, avant tout check de statut.
|
||||
- **Règle** : définir une whitelist explicite des writes autorisés même en état bloqué.
|
||||
|
||||
- Contexte technique : NestJS / guard statut — app-alexandrie 30-03-2026
|
||||
|
||||
@@ -73,3 +73,50 @@ return buildLocalizedPath(locale, "home");
|
||||
- Retourner `null` (accès non bloqué) plutôt que de boucler
|
||||
|
||||
- Contexte technique : Next.js App Router / feature flags tenant — app-template-resto 17-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-server-action-self-request"></a>
|
||||
## Server Action : self-request / loopback HTTP vers sa propre API
|
||||
|
||||
### Risques
|
||||
|
||||
- Latence réseau inutile (aller-retour HTTP interne)
|
||||
- Fragilité sur `APP_URL` en environnement Docker (loopback non résolu)
|
||||
- Double authentification (cookies reconstitués manuellement)
|
||||
- Surface d'attaque SSRF
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `fetch(process.env.APP_URL + '/api/...')` dans une Server Action
|
||||
- Reconstitution manuelle de cookies de session dans l'appel
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Une Server Action peut importer et appeler directement des modules marqués `server-only` sans `fetch` interne — les deux s'exécutent côté serveur.
|
||||
- **Règle** : si tu te retrouves à reconstituer des cookies de session pour faire un `fetch` vers ta propre API depuis une Server Action, c'est le signal que l'appel doit être direct.
|
||||
|
||||
- Contexte technique : Next.js App Router / Server Actions — app-template-resto 31-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-exdev-atomic-write"></a>
|
||||
## Écriture atomique (tmp + rename) : EXDEV si tmp sur device différent
|
||||
|
||||
### Risques
|
||||
|
||||
- `rename()` lève `EXDEV` si le fichier temporaire et la destination sont sur deux devices différents (cas courant Docker bind-mount).
|
||||
- L'erreur survient uniquement en production (Docker) — invisible en dev local.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `Error: EXDEV: cross-device link not permitted, rename '/tmp/...' → '/data/...'`
|
||||
- Upload de fichier fonctionnel en dev, cassé en production Docker
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Créer le fichier temporaire dans **le même répertoire** que la destination finale, pas dans `os.tmpdir()`.
|
||||
- S'assurer que le répertoire cible existe avant l'écriture du fichier temporaire.
|
||||
- **Règle** : `os.tmpdir()` est interdit pour les fichiers qui seront renommés vers un volume Docker bind-mounté.
|
||||
|
||||
- Contexte technique : Node.js / Docker / fichiers media — app-template-resto 31-03-2026
|
||||
|
||||
@@ -304,3 +304,26 @@ if (cursor) {
|
||||
- **Règle** : ajouter un test unitaire "cursor invalide → 400" sur tout endpoint paginé par cursor
|
||||
|
||||
- Contexte technique : NestJS / pagination — app-alexandrie 24-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-enum-like-string-prisma"></a>
|
||||
## Champ enum-like stocké en `String` Prisma — perte de contrainte DB et typage dégradé
|
||||
|
||||
### Risques
|
||||
|
||||
- Aucune contrainte en base sur les valeurs acceptées — insertion de valeurs invalides possible sans erreur DB.
|
||||
- Cast manuel `as EnumType` dans le service masque l'absence de validation Prisma.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `as SomeEnum` dans un service ou repository sur un champ qui provient de la DB
|
||||
- Getter `get model(): any` dans PrismaService pour contourner le typage
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
1. Tout champ à valeurs finies doit être déclaré avec un `enum` Prisma dès la création du modèle — jamais en `String`.
|
||||
2. Si un modèle existant utilise `String`, créer une migration de conversion : `ALTER COLUMN ... TYPE "EnumType" USING ...::"EnumType"`.
|
||||
3. **Signal review** : tout cast `as EnumType` sur une valeur issue de Prisma = dette à corriger immédiatement.
|
||||
|
||||
- Contexte technique : Prisma / PostgreSQL — app-alexandrie 31-03-2026
|
||||
|
||||
@@ -61,3 +61,26 @@ function processLinks(content: string) {
|
||||
- **Règle** : les regex avec flag `/g` ou `/y` utilisées pour transformation de strings → toujours créer via une factory, jamais en singleton de module
|
||||
|
||||
- Contexte technique : TypeScript / React Native — app-alexandrie 24-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-alert-prompt-ios-only"></a>
|
||||
## `Alert.prompt` iOS-only — fonctionnalité silencieusement cassée sur Android
|
||||
|
||||
### Risques
|
||||
|
||||
- `Alert.prompt` ne déclenche rien sur Android (retourne `undefined` silencieusement).
|
||||
- Les tests unitaires passent (mock), mais le flux ne s'exécute jamais sur 50 % des devices en production.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Flux de saisie utilisateur qui fonctionne sur simulateur iOS mais est inactif sur Android
|
||||
- Aucun message d'erreur côté dev ni côté utilisateur
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
1. Ne jamais utiliser `Alert.prompt` dans un projet Expo cross-platform.
|
||||
2. Remplacer par une modale custom : `Modal` + `TextInput` React Native — portable, accessible, testable.
|
||||
3. Wrapper le `TextInput` dans `KeyboardAvoidingView` avec `behavior={Platform.OS === 'ios' ? 'padding' : 'height'}`.
|
||||
|
||||
- Contexte technique : React Native / Expo cross-platform — app-alexandrie 31-03-2026
|
||||
|
||||
@@ -44,3 +44,70 @@
|
||||
- Pour un helper à fallback optionnel : tester explicitement le cas `fallbackToFr=false` (défaut) avec une valeur vide
|
||||
|
||||
- Contexte technique : TypeScript / Jest — app-template-resto 17-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-helpers-copies-tests"></a>
|
||||
## Helpers copiés localement dans les tests (faux positif permanent)
|
||||
|
||||
### Risques
|
||||
|
||||
- La logique réellement exécutée en production peut diverger du helper copié dans le test sans casser aucun test.
|
||||
- Un refactor du module source ne casse pas le test — la couverture est illusoire.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Fonctions utilitaires redéfinies dans `*.spec.ts` plutôt qu'importées depuis le module de production
|
||||
- Tests verts malgré une régression dans le code source
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Les tests doivent importer le module réellement utilisé par l'écran/composant, jamais dupliquer la logique.
|
||||
- Si la logique est partagée entre écran et test, l'extraire dans un utilitaire partagé (single source of truth).
|
||||
- **Checklist review** : aucune fonction de production recopiée dans `*.spec.ts`.
|
||||
|
||||
- Contexte technique : TypeScript / Jest — 30-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-test-ecran-indirect"></a>
|
||||
## Test d'écran indirect — logique UI validée via helper adjacent non relié au flux
|
||||
|
||||
### Risques
|
||||
|
||||
- Le test reste vert même si la logique de décision UI dans le screen diverge du helper testé.
|
||||
- Un changement d'implémentation de l'écran ne casse aucun test.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `*.spec.ts` d'un écran qui n'importe pas le composant/écran mais seulement un helper utilitaire adjacent
|
||||
- Couverture affichée OK mais comportement réel de l'écran non testé
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- La logique de décision UI doit être soit testée via rendu composant (`@testing-library/react-native`), soit extraite dans un module dédié importé par le screen ET par le test (single source of truth).
|
||||
- **Règle** : un test qui n'importe pas le composant écran ni son module de logique ne peut pas valider le comportement de l'écran.
|
||||
|
||||
- Contexte technique : React Native / Jest — 30-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-test-facade-flux-reel"></a>
|
||||
## Test de façade — helpers adjacents validés à la place du flux réel
|
||||
|
||||
### Risques
|
||||
|
||||
- Une tâche d'intégration (conversion, persistance, atomicité, contrat UI) est clôturée alors que les tests ne valident que des helpers purs (chemins, labels, sanitization).
|
||||
- Le pipeline réel, la persistance DB et les transitions UI ne sont jamais exercés.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Tests `*.spec.ts` créés uniquement sur des fonctions utilitaires pures pour une story qui promet un pipeline
|
||||
- La tâche est cochée ✅ mais aucun test n'appelle le module de traitement de production
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Si une tâche promet conversion, statut DB, atomicité ou contrat UI/public : le test doit appeler le module de production correspondant ou un seam injecté unique.
|
||||
- **Règle** : un test qui ne vérifie que des helpers adjacents ne peut pas clôturer une tâche d'intégration.
|
||||
|
||||
- Contexte technique : TypeScript / Jest — app-template-resto 31-03-2026
|
||||
|
||||
@@ -48,3 +48,49 @@
|
||||
- Ne pas faire confiance au status `done` sans preuve dans le code
|
||||
|
||||
- Contexte technique : BMAD / agent Codex — app-template-resto 21-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-file-list-hors-perimetre"></a>
|
||||
## Story validée avec changements hors périmètre non documentés
|
||||
|
||||
### Risques
|
||||
|
||||
- Le reviewer valide un faux scope ou rejette à tort une story correcte.
|
||||
- Des changements source non tracés (working tree dirty) peuvent masquer une implémentation partielle ou des effets de bord.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Tâches `[x]` et File List propre, mais `git status` montre des fichiers modifiés hors story
|
||||
- Aucun bloc "hors périmètre" dans le Dev Agent Record alors que des fichiers non liés ont été touchés
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Si des changements hors story sont présents dans le working tree, documenter un bloc **"hors périmètre"** explicite dans le Dev Agent Record (liste courte + justification).
|
||||
- Ne marquer `done` qu'après clarification de périmètre.
|
||||
- **Règle** : le reviewer croise systématiquement `git diff --name-only` avec la File List avant d'accepter.
|
||||
|
||||
- Contexte technique : BMAD / workflow agent — 30-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-file-list-approximative"></a>
|
||||
## File List approximative — chemins faux ou fichiers source absents
|
||||
|
||||
### Risques
|
||||
|
||||
- Validation d'une implémentation avec traçabilité mensongère.
|
||||
- Chemins fictifs dans la File List non détectés si le reviewer ne croise pas avec `git`.
|
||||
|
||||
### Symptômes
|
||||
|
||||
- File List courte ou générique alors que le diff réel touche de nombreux fichiers source
|
||||
- Fichier listé avec un chemin qui n'existe pas dans le repo
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- **Règle review** : comparer la File List du Dev Agent Record au `git diff --name-only` réel.
|
||||
- Tout fichier source modifié absent de la File List → signaler en **MEDIUM**.
|
||||
- Tout fichier listé avec un chemin inexistant en git → signaler en **HIGH**.
|
||||
|
||||
- Contexte technique : BMAD / workflow agent — app-template-resto 31-03-2026
|
||||
|
||||
@@ -117,34 +117,44 @@ Avant de proposer l'intégration effective:
|
||||
|
||||
# Format de sortie attendu
|
||||
|
||||
Retourner un rapport court avec un bloc par proposition:
|
||||
Produire trois sections, une par décision. Omettre une section si aucune entrée dans la catégorie.
|
||||
Le texte final intégrable n'apparaît **pas** dans le rapport — il est produit lors de l'exécution (option 1) ou sur demande (option 2).
|
||||
|
||||
```md
|
||||
## <DATE — PROJET> — <titre court>
|
||||
Légende confiance : 🟢 HIGH / 🟡 MEDIUM / 🔴 LOW
|
||||
|
||||
Décision : <INTEGRER_KNOWLEDGE | A_DEPLACER_CLAUDE_PROJET | REJETER>
|
||||
Confiance : <HIGH | MEDIUM | LOW>
|
||||
## INTEGRER_KNOWLEDGE
|
||||
|
||||
Justification :
|
||||
Un tableau par domaine (`backend`, `frontend`, `workflow`, etc.), trié par `flux` puis `fichier`. La colonne `Domaine` est remplacée par le sous-en-tête de section.
|
||||
|
||||
- Nouveauté : <DOUBLON_EXACT | DOUBLON_SEMANTIQUE | COMPLEMENT | NOUVEAU>
|
||||
- Portée : <GLOBAL | PROJET>
|
||||
- Motif principal : <1 phrase>
|
||||
### 🔧 Backend
|
||||
|
||||
Action proposée :
|
||||
| Projet | Flux | Fichier | Titre court | Patch | Nouveauté | Confiance |
|
||||
|---|---|---|---|---|---|---|
|
||||
| … | patterns/risques | … | … | ajout/remplacement/fusion | NOUVEAU/COMPLEMENT/DOUBLON_SEMANTIQUE | 🟢/🟡/🔴 |
|
||||
|
||||
- Si INTEGRER_KNOWLEDGE :
|
||||
- Fichier : <chemin exact>
|
||||
- Patch logique : <ajout/remplacement/fusion>
|
||||
- Texte final proposé : <version courte prête à intégrer>
|
||||
- Si A_DEPLACER_CLAUDE_PROJET :
|
||||
- Projet : <nom>
|
||||
- Fichier : <chemin CLAUDE.md résolu ou attendu>
|
||||
- Section : <Leçons apprises | Points sensibles>
|
||||
- Texte final proposé : <version projet>
|
||||
- Si REJETER :
|
||||
- Raison : <doublon/bruit/non-actionnable>
|
||||
```
|
||||
### 🖥️ Frontend
|
||||
|
||||
| Projet | Flux | Fichier | Titre court | Patch | Nouveauté | Confiance |
|
||||
|---|---|---|---|---|---|---|
|
||||
|
||||
### ⚙️ Workflow
|
||||
|
||||
| Projet | Flux | Fichier | Titre court | Patch | Nouveauté | Confiance |
|
||||
|---|---|---|---|---|---|---|
|
||||
|
||||
_(autres domaines si applicable : 🎨 UX, 🔁 n8n, 📦 Product)_
|
||||
|
||||
## 📁 À déplacer vers CLAUDE.md
|
||||
|
||||
| Projet | Titre court | Section | Confiance |
|
||||
|---|---|---|---|
|
||||
| … | … | Leçons apprises/Points sensibles | 🟢/🟡/🔴 |
|
||||
|
||||
## 🗑️ Rejetées
|
||||
|
||||
| Projet | Titre court | Motif |
|
||||
|---|---|---|
|
||||
| … | … | doublon / bruit / non-actionnable |
|
||||
|
||||
# Contraintes de qualité
|
||||
|
||||
|
||||
Reference in New Issue
Block a user