Aller au contenu
🔬 Scénarios réels — 2026

Workflows & Cas Pratiques

Fini les templates abstraits. Ici, on suit des scénarios complets de bout en bout : du premier prompt au résultat final, avec les itérations réelles, les ratés, et les corrections.

1 Workflow : App from scratch

De l'idée au déploiement en 6 étapes. Chaque étape montre le prompt exact utilisé et le résultat obtenu. Scénario : une API de gestion de tâches (todo-app) en Node.js + TypeScript.

Étape 1 — Spécification

On commence par demander à Copilot de structurer notre idée.

Prompt Agent
Je veux créer une API de gestion de tâches (todo).

Stack : Node.js, TypeScript, Express, PostgreSQL, Prisma ORM.
Auth : JWT avec refresh tokens.
Features : CRUD tâches, catégories, priorités, filtres, pagination cursor-based.
Deploy : Docker + Railway.

Génère une spécification technique complète :
1. Liste des endpoints avec méthodes HTTP et payloads
2. Schéma de base de données (entités, relations, indexes)
3. Architecture des dossiers (structure de projet)
4. Liste des packages npm nécessaires
5. Variables d'environnement requises

Ne génère PAS le code encore — juste la spec.
💡
Pourquoi séparer spec et code ? Un prompt qui demande tout d'un coup produit du code bâclé. En demandant d'abord la spec, on peut la valider, ajuster, puis coder sur des bases solides.

Étape 2 — Scaffolding du projet

Avec la spec validée, on demande le squelette.

Prompt Agent
À partir de la spec ci-dessus, initialise le projet.

Génère :
1. package.json avec tous les scripts (dev, build, start, test, lint, db:migrate, db:seed)
2. tsconfig.json (strict mode, paths aliases)
3. .env.example avec toutes les variables
4. Dockerfile multi-stage (dev + prod)
5. docker-compose.yml (app + postgres + redis)
6. Structure de dossiers vide avec fichiers index.ts

Conventions :
- ESLint + Prettier config incluses
- Husky + lint-staged pour pre-commit hooks
- Architecture en couches : routes → controllers → services → repositories

Étape 3 — Modèles de données

Le schéma Prisma complet.

Prompt Agent
Crée le fichier prisma/schema.prisma complet pour la todo-app.

Entités :
- User (id, email, password hash, name, createdAt, updatedAt)
- Task (id, title, description, status [TODO|IN_PROGRESS|DONE], priority [LOW|MEDIUM|HIGH|URGENT], dueDate, userId, categoryId, createdAt, updatedAt)
- Category (id, name, color hex, userId)
- RefreshToken (id, token, userId, expiresAt)

Relations : User 1→N Task, User 1→N Category, Category 1→N Task, User 1→N RefreshToken.
Indexes : Task(userId, status), Task(dueDate), Category(userId).

Ajoute aussi le seed file (prisma/seed.ts) avec 3 users, 5 catégories, 20 tâches réalistes.

Étape 4 — Implémentation couche par couche

On code chaque couche séparément pour garder le contrôle.

Prompt Agent
Implémente la couche "Task" complète.

Fichiers à créer :
1. src/routes/task.routes.ts — Express router avec validation Zod sur chaque route
2. src/controllers/task.controller.ts — Parsing request, appel service, formatting response
3. src/services/task.service.ts — Logique métier (permissions, business rules)
4. src/repositories/task.repository.ts — Queries Prisma optimisées

Endpoints :
- GET /tasks (filtres: status, priority, categoryId, search, pagination cursor)
- GET /tasks/:id
- POST /tasks (validation complète)
- PATCH /tasks/:id (partial update)
- DELETE /tasks/:id (soft delete avec deletedAt)

Chaque fichier doit inclure :
- TypeScript strict (no any)
- Error handling avec classes d'erreurs custom
- Logging structuré (pino)
- JSDoc sur les fonctions publiques

Étape 5 — Tests

On teste chaque couche indépendamment.

Prompt Agent
Crée les tests pour le module Task.

Tests unitaires (Vitest) :
- task.service.test.ts : mock du repository, tester chaque business rule
  - Créer une tâche → success
  - Créer une tâche sans titre → validation error
  - Modifier une tâche d'un autre user → forbidden
  - Supprimer une tâche déjà supprimée → 404

Tests d'intégration (Supertest) :
- task.integration.test.ts : vrai serveur + DB test
  - POST /tasks → 201 + vérifier en DB
  - GET /tasks avec filtres → résultats corrects
  - Auth required → 401 sans token
  - Pagination → cursor fonctionne

Setup : beforeAll crée un user test + token, afterAll clean la DB.
Fixtures : factory functions pour créer des tasks de test.

Étape 6 — Deploy

Configuration du déploiement complet.

Prompt Agent
Configure le déploiement de la todo-app.

GitHub Actions CI/CD :
1. On push to main : lint → test → build → deploy
2. On PR : lint → test → preview deploy

Fichiers à générer :
- .github/workflows/ci.yml
- .github/workflows/deploy.yml
- Dockerfile production (multi-stage, node:20-alpine, ~80MB final)
- railway.toml (ou render.yaml selon la plateforme)
- Health check endpoint GET /health

Bonus :
- Sentry error tracking setup
- Rate limiting en production (express-rate-limit)
- CORS config pour le frontend
- Helmet security headers
📊
Bilan : En 6 prompts (au lieu de tout demander d'un coup), on obtient une app production-ready avec spec, tests, CI/CD. Chaque prompt est vérifiable indépendamment.

2 Workflow : Debug production

Scénario réel : votre API retourne des 500 aléatoires depuis 2h. Le monitoring montre un spike de latence. Voici comment utiliser Copilot méthodiquement pour trouver la root cause.

Alerte & Triage

Premier réflexe : donner le symptôme exact à Copilot.

Prompt Chat
Mon API Node.js/Express (PostgreSQL, Redis cache) retourne des 500 intermittents.

Symptômes :
- Erreur : "Connection terminated unexpectedly" dans les logs
- Commence il y a ~2h, pas de deploy récent
- Fréquence : ~5% des requests (pas toutes)
- Seulement sur les endpoints qui font des queries DB complexes
- Les endpoints qui utilisent le cache Redis fonctionnent OK
- Pas de spike CPU/RAM côté serveur

Donne-moi une liste de 5-7 hypothèses ordonnées par probabilité,
avec pour chacune : comment la vérifier en 1 commande ou 1 query.

Investigation ciblée

On teste l'hypothèse la plus probable.

Prompt Chat
L'hypothèse #1 semble confirmée : pool de connexions PostgreSQL saturé.

Contexte :
- Pool size actuel : 10 (défaut Prisma)
- Concurrent requests : ~200/sec sur le pic
- Certaines queries prennent 2-3 secondes (jointures lourdes)
- Les connexions ne sont pas libérées proprement quand une query timeout

Questions :
1. Comment confirmer à 100% que c'est bien le pool ? (query pg_stat_activity)
2. Quel pool size optimal pour 200 rps avec des queries de 200ms en moyenne ?
3. Montre-moi le code actuel problématique ET le fix
4. Comment ajouter un monitoring du pool pour détecter ça plus tôt ?

Fix & Validation

On applique le correctif et on vérifie qu'il résout le problème.

Prompt Chat
OK, j'ai augmenté le pool à 25 et ajouté un connection timeout de 5s.

Maintenant :
1. Crée un script de load test (k6 ou Artillery) qui reproduit le scénario :
   - 200 req/sec pendant 5 min
   - Mix de requêtes légères (GET /tasks) et lourdes (GET /stats/dashboard)
   - Vérifie : 0% de 500, p99 latency < 500ms

2. Crée un post-mortem template avec :
   - Timeline de l'incident
   - Root cause
   - Fix appliqué
   - Actions préventives (monitoring, alerts)
   - Leçons apprises
⚠️
Pattern clé : Ne jamais demander "fix mon bug". Toujours donner les symptômes précis, les données observées, et demander des hypothèses avant de demander un fix. L'IA est excellente pour le raisonnement systématique, pas pour deviner.

3 Workflow : Documentation technique

De la page blanche à un RFC complet, en passant par un ADR et de la doc API. Le workflow complet en 4 étapes.

ADR (Architecture Decision Record)

Documenter une décision technique importante.

Prompt Agent
Rédige un ADR (Architecture Decision Record) pour cette décision :

Titre : Migration de REST vers GraphQL pour le module Dashboard
Date : 2026-03-01
Statut : Proposé

Context :
- Le dashboard fait actuellement 12 appels REST pour charger la page
- Latence totale : ~2.5s (sérialisé) ou ~800ms (parallélisé)
- Le frontend a besoin de données très spécifiques (over-fetching massif)
- L'équipe de 4 devs connaît REST, 1 seul connaît GraphQL

Format ADR standard :
1. Titre
2. Statut (Proposé / Accepté / Rejeté / Remplacé)
3. Contexte (situation actuelle, problème)
4. Décision (ce qu'on fait)
5. Options considérées (avec pros/cons de chaque)
6. Conséquences (positives et négatives)
7. Plan de migration (étapes concrètes)
8. Critères de succès (métriques mesurables)

RFC (Request for Comments)

Pour les changements majeurs qui nécessitent un consensus d'équipe.

Prompt Agent
Transforme cet ADR en RFC complet pour review par l'équipe.

Ajouter :
- Executive Summary (3 phrases max, pour les managers)
- Diagramme d'architecture (avant / après) en Mermaid
- Estimation d'effort (jours-homme par phase)
- Risques détaillés avec probabilité et impact (matrice)
- Rollback plan si ça ne marche pas
- Section FAQ (anticiper les questions de l'équipe)
- Timeline proposée avec milestones

Ton : technique mais accessible (junior devs doivent comprendre)
Longueur : 2-3 pages A4 max

Documentation API auto-générée

Enrichir le code avec de la documentation qui génère automatiquement des docs lisibles.

Prompt Chat
Voici mon endpoint Express (#file:src/routes/task.routes.ts).

Pour chaque route, génère :
1. JSDoc complet avec @param, @returns, @throws, @example
2. Commentaire OpenAPI/Swagger inline (avec @openapi ou tsoa decorators)
3. Exemples de requêtes cURL pour chaque cas (success, error 400, error 404)
4. Description des edge cases non-évidents

Style : concis mais complet. Un nouveau dev doit comprendre l'endpoint en 30 secondes.

README / Guide d'onboarding

Le document que chaque nouveau dev du projet devrait lire en premier.

Prompt Agent
Génère un README.md complet pour le projet todo-app.

Sections :
1. 🚀 Quick Start (3 commandes pour lancer le projet)
2. 📁 Structure du projet (arbre + description de chaque dossier)
3. 🔧 Configuration (.env, variables, secrets)
4. 🗄️ Base de données (migrations, seed, schéma)
5. 🧪 Tests (comment lancer, coverage, conventions)
6. 🚀 Déploiement (CI/CD, environnements, rollback)
7. 📐 Conventions (naming, commits, PR process)
8. 🤝 Contribuer (setup, workflow, review checklist)
9. 📊 Architecture (diagramme Mermaid des couches)
10. 🐛 Troubleshooting (problèmes fréquents + solutions)

Format : Markdown avec emojis, tables, code blocks.
Audience : dev junior qui rejoint l'équipe.
💡
Astuce : Gardez vos prompts de documentation dans un fichier .prompts/docs.md dans votre repo. Quand le code change, relancez le même prompt pour mettre à jour la doc automatiquement.

4 Avant / Après : Refactoring réel

Des exemples concrets de code "avant" transformé en code propre via des prompts bien construits. Chaque exemple montre le prompt utilisé et le diff résultant.

Exemple 1 : God Function → Clean Architecture

❌ Avant — 1 fonction de 120 lignes
async function handleOrder(req, res) {
  // Validation
  if (!req.body.items) return res.status(400).json({error: 'no items'})
  if (!req.body.userId) return res.status(400).json({error: 'no user'})
  // Check stock
  for (const item of req.body.items) {
    const product = await db.query('SELECT stock FROM products WHERE id = $1', [item.id])
    if (product.rows[0].stock < item.qty) return res.status(400).json({error: 'no stock'})
  }
  // Calculate total
  let total = 0
  for (const item of req.body.items) {
    const product = await db.query('SELECT price FROM products WHERE id = $1', [item.id])
    total += product.rows[0].price * item.qty
  }
  // Apply discount
  if (req.body.coupon) {
    const coupon = await db.query('SELECT * FROM coupons WHERE code = $1', [req.body.coupon])
    if (coupon.rows[0]) total *= (1 - coupon.rows[0].discount / 100)
  }
  // Charge payment
  const payment = await stripe.charges.create({amount: total * 100, currency: 'eur'})
  // Save order
  const order = await db.query(
    'INSERT INTO orders (user_id, total, payment_id) VALUES ($1, $2, $3) RETURNING *',
    [req.body.userId, total, payment.id]
  )
  // Send email
  await sendgrid.send({to: req.body.email, subject: 'Commande confirmée', ...})
  res.json(order.rows[0])
}
✅ Après — Clean Architecture
// route
router.post('/orders', validate(createOrderSchema),
  orderController.create)

// controller
async create(req, res) {
  const order = await orderService.create(
    req.validatedBody
  )
  res.status(201).json(order)
}

// service
async create(dto: CreateOrderDto) {
  await this.stockChecker.verify(dto.items)
  const total = await this.priceCalc
    .calculate(dto.items, dto.coupon)
  const payment = await this.paymentGw
    .charge(total, 'eur')
  const order = await this.orderRepo
    .save({ ...dto, total, paymentId: payment.id })
  await this.notifier
    .orderConfirmed(order)
  return order
}

// Chaque service: testable, isolé, ~20 lignes

Le prompt utilisé :

Prompt Chat
Refactore cette fonction handleOrder en suivant Clean Architecture.

Règles :
- Séparer en 4 couches : route → controller → service → repository
- Chaque fonction fait UNE seule chose (SRP)
- Validation avec schéma Zod (pas de if/else dans le controller)
- Les dépendances externes (Stripe, SendGrid) sont injectées
- Chaque couche est testable indépendamment
- Error handling centralisé (pas de try/catch dans chaque fonction)
- TypeScript strict (interfaces pour chaque DTO)

Montre-moi chaque fichier séparément avec son chemin.

Exemple 2 : Callback Hell → Async élégant

❌ Avant — Callback pyramid
function processData(userId, cb) {
  getUser(userId, (err, user) => {
    if (err) return cb(err)
    getOrders(user.id, (err, orders) => {
      if (err) return cb(err)
      orders.forEach(order => {
        getProducts(order.id, (err, products) => {
          if (err) return cb(err)
          calculateTotal(products, (err, total) =>
            if (err) return cb(err)
            updateOrder(order.id, total, (err) =>
              if (err) return cb(err)
              sendReceipt(user.email, total,
                (err) => {
                  if (err) return cb(err)
                  cb(null, 'done')
              })
            })
          })
        })
      })
    })
  })
}
✅ Après — Async/await + error handling
async function processData(userId: string) {
  const user = await getUser(userId)
  const orders = await getOrders(user.id)

  const results = await Promise.all(
    orders.map(async (order) => {
      const products = await getProducts(order.id)
      const total = calculateTotal(products)
      await updateOrder(order.id, total)
      return { orderId: order.id, total }
    })
  )

  const grandTotal = results
    .reduce((sum, r) => sum + r.total, 0)
  await sendReceipt(user.email, grandTotal)

  return { processed: results.length, grandTotal }
}
// +60% plus lisible, parallélisé, typé

Exemple 3 : SQL brut → ORM optimisé

❌ Avant — N+1 queries
// 1 query pour les users
const users = await db.query('SELECT * FROM users')
// N queries pour les posts (N+1 problem!)
for (const user of users.rows) {
  const posts = await db.query(
    'SELECT * FROM posts WHERE user_id = $1',
    [user.id]
  )
  user.posts = posts.rows
  // N*M queries pour les comments!
  for (const post of user.posts) {
    const comments = await db.query(
      'SELECT * FROM comments WHERE post_id = $1',
      [post.id]
    )
    post.comments = comments.rows
  }
}
// Total: 1 + N + N*M queries 💀
✅ Après — 1 query optimisée
// Prisma avec includes (1 query SQL)
const users = await prisma.user.findMany({
  include: {
    posts: {
      include: { comments: true },
      orderBy: { createdAt: 'desc' },
      take: 10,
    },
  },
  where: { active: true },
})
// Total: 1 query (Prisma génère un JOIN)
// Bonus: typé, paginé, filtré

// Alternative avec raw SQL si besoin de perf:
const users = await prisma.$queryRaw`
  SELECT u.*, json_agg(
    json_build_object('title', p.title,
      'comments', (SELECT json_agg(c.*)
        FROM comments c WHERE c.post_id = p.id))
  ) as posts
  FROM users u
  LEFT JOIN posts p ON p.user_id = u.id
  WHERE u.active = true
  GROUP BY u.id
`
🔑
Clé du refactoring avec l'IA : Montrez toujours le code "avant" en entier, pas un résumé. Nommez explicitement les patterns à appliquer (SRP, DI, Repository pattern...). Demandez le résultat fichier par fichier.

5 Prompt Chaining avancé

Le prompt chaining consiste à enchaîner 3-5 prompts où chaque output alimente le suivant, comme un pipeline. C'est la technique la plus puissante pour les tâches complexes.

Le concept

1️⃣

Analyser

Premier prompt : comprendre et structurer le problème.

2️⃣

Planifier

Deuxième prompt : créer un plan d'action détaillé.

3️⃣

Implémenter

Troisième prompt : coder selon le plan validé.

4️⃣

Valider

Quatrième prompt : tester et corriger.

Cas concret : Créer un système d'authentification complet

Chain 1/4 — Analyse des besoins

Prompt 1 — Analyse
J'ai besoin d'un système d'authentification pour mon app SaaS.

Analyse les besoins et liste :
1. Les user stories (en tant que... je veux... afin de...)
2. Les flux d'auth nécessaires (login, register, forgot password, OAuth, 2FA...)
3. Les risques de sécurité à couvrir (OWASP)
4. Les choix techniques à faire (session vs JWT, stockage tokens, etc.)

Ne propose PAS de solution encore. Juste l'analyse.

Chain 2/4 — Architecture

Prompt 2 — Plan
Basé sur l'analyse précédente, crée l'architecture technique.

Décisions prises :
- JWT avec refresh tokens (access: 15min, refresh: 7j)
- Stockage : httpOnly cookies (pas localStorage)
- OAuth : Google + GitHub via Passport.js
- 2FA : TOTP (Google Authenticator)
- Rate limiting : 5 tentatives/min sur /login

Génère :
1. Diagramme de séquence (Mermaid) pour chaque flux
2. Liste des endpoints avec schémas in/out
3. Schéma de base de données (tables users, sessions, oauth_accounts)
4. Liste des middlewares nécessaires

Chain 3/4 — Implémentation

Prompt 3 — Code
Implémente l'architecture du prompt précédent.

Ordre de priorité :
1. Middleware d'auth (vérification JWT, extraction user)
2. POST /auth/register (avec validation email, hash bcrypt)
3. POST /auth/login (avec rate limiting, retour des 2 tokens)
4. POST /auth/refresh (rotation du refresh token)
5. POST /auth/logout (invalidation du refresh token)
6. POST /auth/forgot-password (envoi email avec token temporaire)

Stack : Express + TypeScript + Prisma + Zod.
Chaque fichier avec le path complet et les imports.

Chain 4/4 — Validation & Tests

Prompt 4 — Tests
Maintenant, valide l'implémentation.

1. Revue de sécurité : vérifie chaque endpoint contre OWASP Top 10
   - Injection ? ✅/❌
   - Broken auth ? ✅/❌
   - XSS via cookies ? ✅/❌
   - CSRF protection ? ✅/❌

2. Tests d'intégration pour le flux complet :
   - Register → Login → Access protected route → Refresh → Logout
   - Login avec mauvais password (5x) → Rate limited
   - Refresh token expiré → 401 → Re-login

3. Si tu trouves des failles, montre le fix.
🔗
Pourquoi le chaining marche : Chaque prompt a un rôle clair (analyser, planifier, coder, tester). L'IA produit un meilleur résultat quand elle n'essaie pas de tout faire à la fois. Et vous pouvez valider/corriger à chaque étape avant de continuer.

6 Workflow : Revue de code assistée

Comment utiliser Copilot pour faire des code reviews systématiques, que ce soit sur vos propres PRs ou celles de votre équipe.

Review multi-dimensionnelle

Prompt Chat
Fais une code review complète de ce fichier (#file:src/services/payment.service.ts).

Analyse sur 6 axes, note chacun de 1 à 5 :

1. 🔒 SÉCURITÉ
   - Injection possible ?
   - Données sensibles exposées ?
   - Validation des inputs ?
   - Gestion des secrets ?

2. ⚡ PERFORMANCE
   - N+1 queries ?
   - Objets non-libérés (memory leaks) ?
   - Opérations bloquantes ?
   - Caching manquant ?

3. 📖 LISIBILITÉ
   - Nommage clair ?
   - Fonctions <30 lignes ?
   - Commentaires utiles (pas évidents) ?
   - Structure logique ?

4. 🧪 TESTABILITÉ
   - Dépendances injectables ?
   - Effets de bord isolés ?
   - Cas limites couverts ?

5. 🏗️ ARCHITECTURE
   - SRP respecté ?
   - Couplage faible ?
   - DRY (pas de duplication) ?

6. 🐛 BUGS POTENTIELS
   - Race conditions ?
   - Null/undefined non-gérés ?
   - Error handling incomplet ?

Format de réponse :
| Axe | Note | Problèmes trouvés | Fix suggéré |
Pour chaque problème : lien vers la ligne exacte + code corrigé.

Review de PR (Pull Request)

Prompt Chat
Voici le diff d'une PR (#selection ou coller le diff).

Review cette PR comme un senior dev exigeant :

1. RÉSUMÉ : que fait cette PR en 2 phrases ?
2. RISQUES : qu'est-ce qui pourrait casser ?
3. COMMENTAIRES : pour chaque changement notable :
   - Ligne + fichier
   - Type : [nit | suggestion | question | bloquant]
   - Commentaire détaillé

4. MISSING : ce qui devrait être dans la PR mais n'y est pas
   (tests, migration, doc, changelog...)

5. VERDICT : Approve / Request changes / Needs discussion

Sois constructif mais direct. Pas de compliments vides.

Review de sécurité ciblée

Prompt Chat
Audit de sécurité sur ces fichiers :
#file:src/auth/login.controller.ts
#file:src/auth/jwt.service.ts
#file:src/middleware/auth.middleware.ts

Checklist OWASP Top 10 (2025) :
- [ ] A01: Broken Access Control
- [ ] A02: Cryptographic Failures
- [ ] A03: Injection
- [ ] A04: Insecure Design
- [ ] A05: Security Misconfiguration
- [ ] A06: Vulnerable Components
- [ ] A07: Auth Failures
- [ ] A08: Data Integrity Failures
- [ ] A09: Logging Failures
- [ ] A10: Server-Side Request Forgery

Pour chaque faille trouvée :
- Gravité (Critical / High / Medium / Low)
- Ligne de code exacte
- Exploit possible
- Fix avec code
🎯
Pro tip : Sauvez vos prompts de review dans un fichier .prompts/review.md. Utilisez #file:.prompts/review.md dans le chat pour lancer la même review standardisée sur chaque PR. Votre équipe aura des reviews cohérentes.

7 Gallery : Prompts ratés → corrigés

Apprendre des erreurs est plus efficace que d'étudier des succès. Voici 10 vrais exemples de prompts qui échouent, pourquoi, et comment les corriger.

#1 — Trop vague

❌ Le prompt raté
Fais-moi un formulaire de login

Pourquoi ça échoue : Aucun contexte. Quelle techno ? Quel style ? Avec validation ? OAuth ? L'IA va deviner et se tromper.

✅ La version corrigée
Crée un formulaire de login en React + TypeScript.

Composant : LoginForm.tsx (function component + hooks)
UI : Tailwind CSS, responsive, dark mode compatible
Champs : email (validation format), password (min 8 chars, show/hide toggle)
Soumission : appel POST /api/auth/login avec fetch, gestion loading/error states
Accessibilité : labels, aria-attributes, focus management
Après login réussi : stocker le token et redirect vers /dashboard

#2 — Demander tout d'un coup

❌ Le prompt raté
Crée une app e-commerce complète avec panier, paiement Stripe,
gestion des stocks, dashboard admin, système de reviews,
notifications push, programme de fidélité, et analytics.

Pourquoi ça échoue : Trop de scope. L'IA va produire du code superficiel pour chaque feature, rien de production-ready.

✅ La version corrigée
Commençons par le module Panier de l'app e-commerce.

Stack : Next.js 14, TypeScript, Prisma, PostgreSQL.

Module : CartService
Fonctionnalités :
1. Ajouter un produit (avec vérification stock)
2. Modifier la quantité
3. Supprimer un item
4. Calculer le total (avec TVA)
5. Persister le panier (DB pour users connectés, localStorage pour guests)

Interface CartItem : { productId, name, price, quantity, imageUrl }

Génère : service + repository + API routes + tests unitaires.
On fera Stripe dans un prochain prompt.

#3 — Pas de format de sortie

❌ Le prompt raté
Explique-moi les design patterns

Pourquoi ça échoue : Trop large, pas de format demandé. L'IA va écrire un essai de 3000 mots qu'on ne lira pas.

✅ La version corrigée
Liste les 5 design patterns les plus utiles en TypeScript/Node.js.

Pour chaque pattern, donne EXACTEMENT :
- Nom + catégorie (creational/structural/behavioral)
- Quand l'utiliser (1 phrase)
- Quand NE PAS l'utiliser (1 phrase)
- Code exemple concret en TypeScript (max 20 lignes)
- Cas réel dans un projet Node.js

Format : tableau Markdown avec une section code par pattern.

#4 — Ignorer le contexte existant

❌ Le prompt raté
Crée une fonction d'authentification

Pourquoi ça échoue : Ne référence pas le code existant. L'IA va créer quelque chose d'incompatible avec votre projet.

✅ La version corrigée
En regardant mon projet actuel :
- #file:src/middleware/auth.ts (middleware existant)
- #file:src/models/user.ts (modèle User avec Prisma)
- #file:src/config/env.ts (variables d'environnement)

Ajoute la fonctionnalité "forgot password" :
1. POST /auth/forgot-password → envoie un email avec un token (expire 1h)
2. POST /auth/reset-password → vérifie le token et met à jour le password

Contraintes :
- Utiliser le même style de code que auth.ts
- Réutiliser le modèle User existant
- Le token doit être stocké hashé en DB (pas en clair)
- Rate limit : max 3 demandes/heure par email

#5 — Pas de contraintes de qualité

❌ Le prompt raté
Crée un endpoint pour uploader des fichiers

Pourquoi ça échoue : Pas de contraintes de sécurité, taille, format. L'IA va faire un upload basique sans protection.

✅ La version corrigée
Crée POST /api/files/upload avec multer + S3.

Contraintes de sécurité :
- Types autorisés : image/jpeg, image/png, application/pdf UNIQUEMENT
- Taille max : 10MB
- Scan antivirus : vérifier le magic number du fichier (pas juste l'extension)
- Nommage : UUID v4 + extension originale (pas le nom uploadé)
- Bucket S3 : privé, presigned URLs pour l'accès (expire 1h)

Contraintes de performance :
- Streaming (ne pas charger le fichier entier en mémoire)
- Compression des images >2MB (sharp)
- Thumbnails automatiques pour les images (200x200)

Error handling : messages clairs pour chaque type d'erreur.
Tests : fichier valide, fichier trop gros, mauvais format, fichier malicieux (.exe renommé en .jpg).

#6 — Oublier l'error handling

❌ Le prompt raté
Crée une fonction qui appelle l'API GitHub pour récupérer les repos d'un user
✅ La version corrigée
Crée une fonction getGitHubRepos(username: string) en TypeScript.

Happy path : retourne les repos publics triés par stars.

Error handling COMPLET :
- 404 : user n'existe pas → throw UserNotFoundError
- 403 : rate limited → retry avec exponential backoff (max 3 retries)
- 500 : GitHub down → fallback sur le cache (Redis, TTL 5min)
- Network error : timeout de 5s, retry 1x
- Données invalides : validation Zod du response body

Return type : Result<Repo[], GitHubError> (pattern Result, pas d'exceptions silencieuses)
Logging : chaque cas d'erreur est loggé avec le contexte (username, status, latency)

#7 — Confondre Chat et Agent

❌ Le prompt raté (dans le Chat)
Restructure tout mon projet en ajoutant un dossier services,
déplace les fichiers, mets à jour les imports, et lance les tests.

Pourquoi ça échoue : Le Chat ne peut pas modifier des fichiers ni lancer des commandes. C'est un job pour le mode Agent.

✅ La version corrigée (en mode Agent)
@workspace Restructure le projet :

1. Crée un dossier src/services/ s'il n'existe pas
2. Déplace la logique métier de src/controllers/*.ts vers src/services/*.ts
   - Chaque controller ne doit garder que le parsing de request + response formatting
   - La logique va dans le service correspondant
3. Mets à jour tous les imports dans les fichiers affectés
4. Lance les tests pour vérifier que rien n'est cassé
5. Montre-moi le résumé des changements

#8 — Prompt non-itératif

❌ Le prompt raté
Le code que tu as généré ne marche pas, refais-le correctement.

Pourquoi ça échoue : "Ne marche pas" = zéro information. L'IA va reproduire la même erreur ou en créer une nouvelle.

✅ La version corrigée
Le code généré a ce problème :

Erreur : TypeError: Cannot read property 'map' of undefined
Fichier : src/services/task.service.ts, ligne 42
Contexte : ça arrive quand l'utilisateur n'a aucune tâche (tasks = null au lieu de [])

Ce qui devrait se passer : retourner un tableau vide, pas crasher.

Corrige en :
1. Ajoutant un null check avant le .map()
2. Vérifiant que le repository retourne toujours [] (jamais null)
3. Ajoutant un test pour ce cas edge

#9 — Copier-coller sans adapter

❌ Le prompt raté
Fais la même chose que dans l'autre fichier mais pour les commandes

Pourquoi ça échoue : "L'autre fichier" = lequel ? "La même chose" = quoi exactement ? L'IA n'a pas de mémoire entre les conversations.

✅ La version corrigée
Crée le module Order en suivant exactement la même structure que
#file:src/modules/task/ :
- order.routes.ts (mêmes patterns de validation Zod)
- order.controller.ts (même structure try/catch + response format)
- order.service.ts (même pattern d'injection de dépendances)
- order.repository.ts (même pattern Prisma)

Différences avec Task :
- Order a un statut workflow : DRAFT → CONFIRMED → SHIPPED → DELIVERED → CANCELLED
- Order contient des OrderItems (relation 1→N)
- Le total est calculé (pas stocké directement)

#10 — Résultat sans tests

❌ Le prompt raté
Crée un système de notifications en temps réel avec WebSocket
✅ La version corrigée
Crée un module de notifications en temps réel.

Tech : Socket.IO + Express + TypeScript + Redis (pub/sub pour multi-instance).

Implémentation :
1. NotificationService : créer, lire, marquer comme lu
2. WebSocket handler : auth par token, rooms par userId
3. Redis adapter : pub/sub pour synchroniser N instances du serveur

Tests OBLIGATOIRES :
- Unit : NotificationService.create() → émet un event
- Intégration : Client WS se connecte → reçoit une notification en <100ms
- Edge case : Client déconnecté → notifications stockées → livrées à la reconnexion
- Load : 100 clients simultanés → toutes les notifications arrivent
- Sécurité : Client A ne reçoit PAS les notifications de Client B

Sans les tests, le code n'est pas considéré comme terminé.
📚
Règle générale : Un prompt raté manque toujours au moins un de ces éléments : contexte (quoi, où, avec quoi), format (comment présenter le résultat), contraintes (sécurité, perf, qualité), ou vérification (tests, validation).

8 Cheat Sheet récapitulatif

Tableau condensé de tous les patterns essentiels des 4 guides, avec le contexte d'utilisation et le prompt-clé pour chacun.

🎯 Les patterns fondamentaux (index3)

PatternQuand l'utiliserPrompt-clé
CITERTout prompt structuréContexte: ... / Intention: ... / Ton: ... / Exemple: ... / Résultat: ...
Few-shotL'IA ne comprend pas le formatExemple 1: input → output / Exemple 2: input → output / Maintenant: ...
Chain-of-thoughtRaisonnement complexeRéfléchis étape par étape avant de coder. Montre ton raisonnement.
Tone expliciteContrôler le style généréTon: [senior dev pragmatique / junior friendly / documentation formelle]
Thinking stepDécisions architecturalesAvant de coder, explique 3 approches possibles avec pros/cons.
RôleExpertise spécifiqueTu es un expert [sécurité / performance / UX]. Revois ce code.
Contraintes négativesÉviter les piègesNe pas utiliser [any / var / class components / jQuery]

⚔️ Les patterns dev avancé (index4)

PatternQuand l'utiliserPrompt-clé
API complèteNouveau service backendAPI REST v1 pour [domaine]. OpenAPI + implémentation + tests.
Micro-servicesDécomposer un monolitheDécoupe par bounded context DDD. Events + Docker Compose.
GraphQL optimiséDashboard/BFF complexeSchema + DataLoader + complexity analysis + field-level auth.
CI/CD pipelineNouveau projet à déployerLint → Test → Build → Security scan → Deploy staging → E2E → Prod.
Zero-downtime DBMigration critiqueExpand → Migrate → Contract. Rollback plan à chaque étape.
Root Cause AnalysisBug productionSymptômes → Hypothèses ordonnées → Test chaque → Fix minimal.

🌍 Les patterns pour tous (index5)

PatternQuand l'utiliserPrompt-clé
Email proCommunication formelleEmail pour [contexte]. Ton [X]. Points: 1. 2. 3. Salutation [formelle].
Article/BlogCréation de contenu[Type] sur [sujet]. Public [persona]. Hook + corps + CTA. SEO keywords.
Analyse donnéesComprendre un datasetAnalyse [data]. Tendances + anomalies + recommandations + visualisations.
Business planStratégie/planificationPlan pour [projet]. Objectif SMART. Phases + risques + KPIs.
Learning pathApprentissage structuréParcours [sujet]. Niveau [X]. Durée [Y]. Modules + exercices + projet final.
Image genCréation visuelleSujet + Style + Composition + Palette + Mood + Format + À éviter.

🔬 Les patterns workflow (cette page)

PatternQuand l'utiliserPrompt-clé
App from scratchNouveau projetSpec → Scaffold → Models → Code → Tests → Deploy (6 prompts).
Debug productionIncident en coursSymptômes → Hypothèses ordonnées → Investigation → Fix → Post-mortem.
Doc techniqueADR/RFC/READMEFormat standard + contexte + options + conséquences + plan.
RefactoringCode legacy à moderniserCode avant complet + patterns cibles + résultat fichier par fichier.
Prompt chainingTâche complexe multi-étapesAnalyser → Planifier → Implémenter → Valider (4 prompts séquentiels).
Code reviewPR review systématique6 axes (sécu/perf/lisib/test/archi/bugs). Note + problèmes + fix.
🏆
Le résumé ultime : Un bon prompt = Contexte précis + Format de sortie explicite + Contraintes de qualité + Demande de tests/validation. Maîtrisez ces 4 éléments et vous maîtrisez le prompt engineering.