Garder la main
Sommaire
09Chapitre 9·Variable (hands-on)·Tous niveaux

Labs pratiques

Exercices guidés par stack

NestJS, Next.js, Laravel, DevOps — applications du cycle Explore → Plan → Code → Verify avec prompts exacts.

Ce que tu sauras faire
  • 01Générer une API REST + tests avec Claude Code (NestJS)
  • 02Refactorer un composant Next.js avec Cursor
  • 03Mener une migration DB en Spec-Driven (Laravel)
  • 04Bâtir un pipeline CI avec revue IA automatisée

Lab 1 — 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 2 — Next.js : Refactoring avec Context Engineering

Durée : 30-45 min · Niveau : intermédiaire · Prérequis : projet Next.js existant, Module 4 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 3 — 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 4 — DevOps : Pipeline CI/CD avec revue IA

Durée : 45-60 min · Niveau : intermédiaire · Prérequis : projet sur GitHub, Module 6 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é (réutilise l'approche du Module 6, ou l'action officielle anthropics/claude-code-action) 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

Lab 5 — Python / FastAPI : endpoint async avec SQLAlchemy 2.x

Durée : 45-60 min · Niveau : intermédiaire · Prérequis : projet FastAPI, Module 3 lu · Livrable : endpoint POST /articles async + tests pytest verts

Stack : Python 3.12+, FastAPI 0.115+, SQLAlchemy 2.x async, Pydantic v2

Setup du contexte

# 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 6 — 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 + post-mortem une page

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

// .claude/settings.json
{
  "mcpServers": {
    "sentry": {
      "command": "npx",
      "args": ["-y", "@sentry/mcp-server"],
      "env": {
        "SENTRY_AUTH_TOKEN": "${env:SENTRY_AUTH_TOKEN}",
        "SENTRY_ORG": "my-org",
        "SENTRY_PROJECT": "api"
      }
    }
  }
}

Sentry propose aussi un serveur MCP hébergé (OAuth, sans token local). Vérifie la méthode courante sur la doc Sentry avant de te rabattre sur le npx.

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 — Post-mortem

Prompt
Rédige le post-mortem INC-[date]-[id] en suivant les 5 questions du Module 7 §5. Si le commit d'origine porte un trailer `AI-Assisted:`, reporte-le. Conclus par au moins une action qui modifie le contexte ou un prompt — pour que ce type de bug ne repasse plus. Une page A4 max.

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, 4, 5 et 8.

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.