Équiper un codebase existant, puis appliquer Explore → Plan → Code → Verify sur NestJS, Next.js, Laravel, FastAPI, la CI et un incident de prod.
Ce que tu sauras faire
01Équiper un vrai codebase en contexte et en tests avant tout le reste
02Appliquer le cycle Explore → Plan → Code → Verify sur des cas réels
03Valider un plan une fois, puis dérouler par blocs en relisant le diff
04Couvrir NestJS, Next.js, Laravel, CI/CD, FastAPI et l'incident en prod
Lab 1 — Équiper un codebase existant
Durée : 45-60 min · Niveau : tous · Prérequis : un vrai projet, si possible un que tu connais mal · Livrable : un fichier de contexte qui tient, un filet de tests sur une zone, et une session mesurée
C'est le lab à faire en premier, et de préférence sur ton projet le moins reluisant. Les six autres partent d'un environnement propre ; celui-ci construit l'environnement. Il applique le Module 4 (archéologie et filet) et le Module 5 (contexte), et tout le reste devient plus facile ensuite.
Étape 1 — Une session entièrement en lecture
Aucune écriture pendant toute cette étape. On ferme la porte plutôt que de compter sur sa bonne volonté — chez Claude Code, le plan mode ; ailleurs, l'équivalent de ton outil, ou une branche jetable (Module 4 §2) :
claude --permission-mode plan
Prompt
Tu découvres ce projet. Je le connais mal moi aussi, donc ne compte pas sur
moi pour rattraper tes erreurs : dis-moi ce dont tu n'es pas sûr.
Livre-moi, sans écrire un seul fichier :
1. À quoi sert ce projet, en trois lignes, déduites du code et non du README.
2. Comment on le lance, on le teste, on le construit. Cite le fichier qui te
le prouve (package.json, Makefile, CI, composer.json...).
3. Les cinq répertoires où se passe l'essentiel du travail, et ce que fait chacun.
4. L'état réel des tests : y en a-t-il, tournent-ils, que couvrent-ils ?
5. Ce que tu n'as pas compris.
Le point 5 est celui qu'on lit en premier. Le point 2 est celui qui va directement dans le fichier de contexte : ce sont les commandes qu'aucun agent ne peut deviner.
Étape 2 — Extraire les conventions plutôt que les inventer
Prompt
Lis @[3 ou 4 fichiers de couches différentes : une route, un service, un test].
Déduis les conventions réellement appliquées : nommage, structure, gestion
des erreurs, accès aux données, style de tests.
Pour chacune : sa formulation en une ligne, sur combien de fichiers de
l'échantillon elle tient, et si elle est systématique ou ponctuelle.
Ne me dis pas ce qui serait une bonne pratique. Dis-moi ce que ce code fait.
Puis c'est ton tour, et cette partie ne se délègue pas. Tu tries en trois catégories : ce qu'on impose, ce qu'on tolère sans l'étendre, ce qu'on interdit désormais. La deuxième catégorie est celle qui empêchera l'agent de « nettoyer » l'ancien code à chaque passage (Module 4 §5).
Étape 3 — Écrire le fichier, et vérifier qu'il est chargé
Écris ton AGENTS.md (le Starter Pack donne le squelette), puis le CLAUDE.md d'une ligne qui l'importe :
@AGENTS.md
Et surtout, vérifie. C'est l'étape que tout le monde saute et c'est celle qui échoue en silence :
/context
Ton fichier doit apparaître sous Memory files. S'il n'y est pas, tout ce que tu viens d'écrire ne sert à rien, et aucun message d'erreur ne te le dira. Sur un autre outil, cherche son équivalent : ce qui compte est d'avoir une preuve que le fichier est chargé, jamais une supposition.
Étape 4 — Poser un filet sur une zone, une seule
Choisis la fonction que tu vas devoir modifier bientôt, celle qui te fait peur. Pas le module entier.
Prompt
Objectif : figer le comportement actuel de @[fonction], pas l'améliorer.
Écris des tests [ton runner] qui capturent ce que le code fait aujourd'hui :
cas nominal, chaque branche conditionnelle, valeurs limites, comportement
en cas d'échec.
IMPORTANT: si un comportement te semble être un bug, encode-le tel quel avec
un commentaire `// comportement actuel, à discuter`. Ne le corrige pas.
Puis casse le code exprès. Change un > en >=, relance la suite. Si tout reste vert, tes tests n'observent rien : reprends-les. Ce contrôle prend deux minutes et c'est lui qui décide si le filet en est un.
Étape 5 — Mesurer ce que ça coûte
/context → combien ton contexte permanent occupe réellement
/usage → ce que la session a consommé
Ton contexte permanent doit rester sous 5 % de la fenêtre (Module 5 §9). Au-delà, tu n'élagues pas des règles utiles : tu sors les règles spécialisées vers .claude/rules/ avec un champ paths.
Ce que tu dois avoir à la fin
Checklist0 / 6
Lab 2 — NestJS : API REST avec Auth JWT
Durée : 45-60 min · Niveau : intermédiaire · Prérequis : NestJS installé, Module 3 lu · Livrable : module auth avec tests E2E
Setup du contexte
<!-- CLAUDE.md pour ce lab -->
# Lab NestJS Auth## Stack- NestJS 10, TypeScript 5.x, TypeORM + PostgreSQL 15
- @nestjs/jwt + Passport, class-validator
- Tests : Jest + Supertest
## Conventions- Architecture : Module / Controller / Service / Repository
- DTOs typés (jamais d'entité retournée directement)
- Erreurs : HttpException avec messages clairs
- IMPORTANT: bcrypt cost ≥ 12, jamais de mot de passe en clair après hash
Phase EXPLORE
Prompt
[ANALYSE UNIQUEMENT — PAS DE CODE]
Explore la structure du projet NestJS.
Identifie :
1. Les modules existants et leur organisation
2. Comment la config est gérée (ConfigModule ?)
3. La structure TypeORM (entities, migrations)
4. Si un système d'auth existe déjà, même partiel
Livre un rapport de 10-15 lignes.
Phase PLAN
Prompt
Je veux une authentification JWT avec : register, login, refresh, logout,
guard JWT réutilisable et une route protégée /me.
Contrainte importante : le logout doit réellement invalider le refresh
token (rotation + denylist côté serveur). Un JWT d'accès reste valide
jusqu'à expiration — c'est le refresh qu'on révoque.
Sur la base de l'exploration, propose un plan d'implémentation : étapes
numérotées, fichiers concernés, critère de validation par étape, et
regroupées en 3 blocs livrables.
Ne génère pas de code encore. Attends ma validation du plan.
Phase CODE
Prompt
Plan validé. Implémente-le bloc par bloc :
Bloc 1 — entité User + migration + config JWT (secret via env)
Bloc 2 — register/login (hash bcrypt) + DTOs + guard JWT + /me
Bloc 3 — refresh token avec rotation + logout (denylist)
Arrête-toi à la fin de chaque bloc : je relis le diff avant le suivant.
Si tu t'écartes du plan validé, signale-le au lieu d'improviser.
Phase VERIFY
Prompt
Agis en QA Engineer senior. Génère des tests E2E (Supertest + Jest)
couvrant ces 5 scénarios essentiels :
1. Register → 201 + tokens / email déjà utilisé → 409
2. Login bon mot de passe → 200 / mauvais → 401
3. /me sans token → 401 / avec token valide → 200
4. Refresh avec token valide → nouveaux tokens (ancien refresh invalidé)
5. Logout → le refresh token utilisé ensuite est refusé → 401
Utilise une DB éphémère (Testcontainers PostgreSQL, ou better-sqlite3 si
le schéma le permet). Pas de mock d'ORM.
Lab 3 — Next.js : Refactoring avec Context Engineering
Durée : 30-45 min · Niveau : intermédiaire · Prérequis : projet Next.js existant, Module 5 lu · Livrable : composant migré Class → Functional + hooks, tests verts
Setup CLAUDE.md
# Lab Next.js Refactoring## Stack- Next.js 15 (App Router), TypeScript 5.x, React 19
- Tailwind CSS
- Tests : Vitest + React Testing Library
- State : Zustand (pas de Redux)
## Conventions composants- Functional components uniquement
- Props typées par interface : interface ButtonProps {}
- Export named uniquement (pas de default export pour les composants)
- Fichiers : ComponentName.tsx + ComponentName.test.tsx dans le même dossier
## Anti-patterns à éviter- Pas de useEffect pour fetch (Server Components ou React Query)
- Pas de prop drilling > 2 niveaux (utiliser Zustand)
- Pas d'inline styles (Tailwind uniquement)
Workflow de refactoring
Prompt
# EXPLORE
[ANALYSE UNIQUEMENT]
Analyse le composant @src/components/UserProfile.tsx
Identifie : type de composant (class/functional ?), props et typage,
état local et usage, effets de bord, tests existants.
# PLAN
Propose le plan de migration vers functional component + hooks, props
interface stricte, Zustand si état partagé. Liste d'étapes. Attends ma
validation.
# CODE
Plan validé : implémente le composant refactorisé d'une traite.
Respecte STRICTEMENT le CLAUDE.md. Garde l'API externe identique
(mêmes props). C'est un seul composant — pas besoin de découper.
# VERIFY
Agis en QA.
1. Lance `npm run test -- UserProfile`
2. Si des tests échouent, identifie pourquoi (régression vs test obsolète)
3. Génère les tests manquants pour les nouveaux hooks
4. Vérifie que l'accessibilité n'a pas régressé (attributs aria-*)
Lab 4 — Laravel : Migration et Soft Delete
Durée : 30-45 min · Niveau : intermédiaire · Prérequis : Laravel 11+ installé, Module 3 lu · Livrable : migration deleted_at, modèle SoftDeletes, tests Pest verts
# CLAUDE.md Laravel## Stack- Laravel 11+, PHP 8.3+
- Eloquent ORM + MySQL 8
- Tests : Pest (pas PHPUnit)
- API Resources pour les réponses
## Conventions- Repository Pattern (interface + implémentation)
- Form Requests pour la validation
- API Resources pour la transformation
- Soft deletes via le trait SoftDeletes d'Eloquent
## Commandes
php artisan serve # Dev
php artisan test # Tests (Pest)
php artisan migrate # Migrations
./vendor/bin/pint # Linter
Lab : Implémenter le soft delete sur User
Prompt
# EXPLORE
Analyse le modèle User et UserRepository.
Identifie : la méthode delete actuelle, les scopes existants, les
relations qui pourraient être affectées, les tests existants.
# PLAN
Propose le plan pour migrer vers SoftDeletes Eloquent (migration deleted_at,
trait sur le modèle, adaptation du repository : withTrashed/onlyTrashed/
restore, tests). Attends ma validation.
# CODE
Plan validé : implémente-le d'une traite (migration → modèle → repository).
Arrête-toi à la fin pour que je relise le diff avant les tests.
# VERIFY (Pest)
Génère des feature tests Pest :
- Soft delete → user non retourné dans les queries normales
- withTrashed → user visible
- restore → user revient dans les queries normales
- forceDelete → suppression physique
- Cascade sur les relations si applicable
Lab 5 — DevOps : Pipeline CI/CD avec revue IA
Durée : 45-60 min · Niveau : intermédiaire · Prérequis : projet sur GitHub, Module 6 §7 lu · Livrable : workflow .github/workflows/ai-review.yml avec 3 jobs (quality, ai-security-review, changelog)
Prompt
# EXPLORE
Analyse les workflows GitHub Actions existants (.github/workflows/).
Identifie les jobs actuels et ce qui manque.
# PLAN
Je veux un pipeline en 3 jobs :
1. quality : lint + test + coverage check (> 80 %)
2. ai-security-review : sur les PRs uniquement, commente seulement si
problème trouvé (action officielle anthropics/claude-code-action,
voir Module 6 §7)
3. changelog : sur merge en main, génère les notes depuis les commits
Conventional Commits depuis le dernier tag
Propose le plan : jobs, dépendances, permissions minimales par job.
Contraintes transverses : npm ci (pas npm install), cache des deps,
secrets via GitHub Secrets, fail si coverage < 80 %.
Attends ma validation.
# CODE
Plan validé : génère le fichier .github/workflows/ai-review.yml complet
en une fois. Je relis le YAML entier avant de commit.
# VERIFY — checklist de relecture
- [ ] Aucun secret en clair dans le YAML (tout via secrets.*)
- [ ] Permissions minimales par job (contents: read, pull-requests: write)
- [ ] Cache des dépendances configuré
- [ ] Jobs parallélisés quand c'est possible
- [ ] Le job ai-security-review ne tourne que sur pull_request
- [ ] Notification en cas d'échec
# CLAUDE.md (extrait spécifique au lab)## Stack- Python 3.12+, FastAPI 0.115+
- SQLAlchemy 2.x **async** uniquement (pas de Session synchrone)
- Pydantic v2 pour les schémas
- pytest + pytest-asyncio + httpx pour les tests
## Conventions- Fichiers par feature : `app/<feature>/{router,schemas,models,service}.py`- Routes ne contiennent JAMAIS de logique métier — tout passe par `service.py`- Dépendances FastAPI : injection via `Depends()`, jamais de globals
- Async partout : pas de `requests`, utiliser `httpx.AsyncClient`## Tests- Base de test isolée par test (SQLite async via aiosqlite, ou Postgres jetable)
- Fixtures dans `conftest.py`, factory-boy pour les seeds
- Marker `@pytest.mark.asyncio` sur les tests async
## Anti-patterns
IMPORTANT: SQLAlchemy 2.x style uniquement (`Mapped`, `mapped_column`, `select().where()`) — pas de raw SQL ni de syntaxe v1.
Phase EXPLORE
Prompt
[ANALYSE UNIQUEMENT — PAS DE CODE]
Explore la structure du projet.
Identifie :
1. Comment les routes existantes sont organisées (par feature ? par couche ?)
2. Comment SQLAlchemy est initialisé (engine, sessionmaker, dépendance FastAPI)
3. Comment Pydantic est utilisé (schémas In/Out séparés ou unifiés ?)
4. Quels fixtures existent dans conftest.py
Livre un rapport de 10-15 lignes.
Phase PLAN
Prompt
Je veux ajouter un endpoint `POST /api/v2/articles` qui :
- Reçoit un payload `{title, body, tags: string[]}`
- Crée un article en DB
- Lie ou crée les tags (many-to-many)
- Retourne l'article créé avec ses tags
Sur la base de ton exploration, propose un plan en étapes numérotées,
regroupées en 2 blocs (modèles+migration, puis service+route+schemas).
Format : Étape | Fichier(s) | Action | Critère de validation.
Identifie les edge cases :
- Tag vide ou trop long
- Tag dupliqué dans la liste
- Conflit de slug si auto-généré
Ne génère pas de code encore. Attends ma validation.
Phase CODE
Prompt
Plan validé. Implémente-le par blocs :
Bloc 1 — modèle Article + relation many-to-many Tag + migration Alembic
Bloc 2 — schemas Pydantic + service + route POST
SQLAlchemy 2.x style, annotations de types complètes.
Arrête-toi à la fin de chaque bloc pour que je relise le diff.
Phase VERIFY
Prompt
L'implémentation est terminée.
Agis maintenant en QA Engineer.
1. Lance `pytest app/articles -v`
2. Lance `ruff check app/articles`
3. Lance `mypy app/articles`
4. Génère les tests manquants pour les edge cases identifiés en PLAN
5. Relance et vérifie qu'ils passent
6. Test httpx contre `POST /api/v2/articles` avec 3 payloads :
- Cas nominal
- Payload invalide (titre vide)
- Tag dupliqué dans la liste
Rapport : tests passés | warnings ruff/mypy | tests ajoutés.
Lab 7 — Production Incident Response avec Sentry MCP
Durée : 30-45 min · Niveau : senior · Prérequis : projet en prod connecté à Sentry, MCP Sentry configuré · Livrable : PR avec fix, test de non-régression et garde-fou versionné
Utiliser Claude Code en mode incident commander : récupérer les infos Sentry, formuler une hypothèse, la valider, proposer un fix minimal, documenter.
Setup MCP
Sentry propose un serveur MCP hébergé (OAuth, sans token local à gérer). C'est la voie à privilégier ; vérifie l'URL courante sur la doc Sentry avant de te rabattre sur une install locale.
# Portée project : le serveur atterrit dans .mcp.json, versionné avec le repo
claude mcp add --transport http --scope project sentry <url-mcp-sentry>
# Vérifie que la connexion est bien établie avant de commencer le lab
claude mcp list
Si tu dois passer par un serveur local en stdio, le .mcp.json produit ressemble à ça :
// .mcp.json (racine du projet, pas .claude/settings.json){"mcpServers":{"sentry":{"command":"npx","args":["-y","@sentry/mcp-server"],"env":{"SENTRY_AUTH_TOKEN":"${SENTRY_AUTH_TOKEN}","SENTRY_ORG":"my-org","SENTRY_PROJECT":"api"}}}}
Phase 1 — Capture
Prompt
[LECTURE SEULE] Via le MCP Sentry, cartographie le top 5 des issues non
résolues des 24 dernières heures (titre, première/dernière occurrence,
utilisateurs affectés, release). Pas de fix encore.
Phase 2 — Triage
Prompt
[LECTURE SEULE] Pour l'issue à plus fort impact : récupère le détail
(stack trace, breadcrumbs, requête), identifie fichier:ligne, lis le code
autour (max 50 lignes). Formule 2-3 hypothèses classées par probabilité,
chacune avec sa méthode de validation.
Phase 3 — Fix
Prompt
On valide l'hypothèse n°1 : [description].
Fix minimal (pas de refactoring opportuniste) + test qui reproduit le bug
(rouge avant le fix). Vérifie que le test passe. Ne touche à aucun autre
fichier.
Phase 4 — Empêcher la récidive
C'est la question du Module 8 §4, appliquée pour de vrai : est-ce que l'agent
va me le refaire ?
Prompt
Le fix est validé. Réponds à une seule question : ce bug, un agent peut-il
le réintroduire à partir de nos fichiers de contexte actuels ?
Si oui, propose les deux formes de garde-fou et dis laquelle est la plus sûre ici :
1. Une ligne à ajouter dans le fichier de contexte du projet.
2. Un test de non-régression qui échoue tout seul si le pattern revient.
Si le commit d'origine porte un trailer `AI-Assisted:`, reporte-le dans la
description de PR. Pas de rapport d'incident : la PR doit contenir le fix,
le test, et le garde-fou. Rien de plus.
Ressources complémentaires
Templates à reprendre
Le Starter Pack du guide est sur la page dédiée /templates :
un fichier de contexte (AGENTS.md) qui marche pour tous les outils, une
configuration Claude Code avec des permissions sécurisées par défaut, un
hook qui bloque l'écriture de fichiers contenant des secrets, et trois
slash commands (/audit-security, /test-gen, /release-notes). Tout
est aligné avec les modules 3, 5, 6 et 9.
Pour le reste (Skills spécialisés, serveurs MCP, agents prêts à l'emploi),
le catalogue de référence est aitmpl.com, un
catalogue communautaire de composants pour Claude Code. La page Templates
signale ceux qu'on recommande spécifiquement.