joechrisnaldy/production-readiness

À utiliser pour les revues de code, les audits de sécurité ou de fiabilité, les vérifications de préparation à la production, et avant de concevoir ou de modifier l'authentification, les modèles de données, les paiements, les intégrations externes, les tâches en arrière-plan, la mise en cache ou le déploiement. Contient une checklist de 150 éléments couvrant la sécurité, les données, la concurrence, la résilience, la messagerie, le réseau, la mise en cache, les performances, les API, l'observabilité, les tests, la livraison, la reprise après sinistre, le côté client et les fonctionnalités LLM.

Qu'est-ce que production-readiness ?

Cette compétence fournit une checklist complète de préparation à la production, conçue pour guider les développeurs et les réviseurs à travers les aspects essentiels de la construction et de l'exploitation de systèmes robustes. Elle couvre 150 éléments répartis en 14 catégories, allant de la sécurité et du contrôle d'accès à la gestion des données, la concurrence, la résilience, la mise en cache, les API, l'observabilité et les tests. L'outil est conçu pour être utilisé lors des revues de code et des audits, et s'adapte au stade du projet (Prototype, MVP, Production ou Scale) pour se concentrer sur ce qui est réellement pertinent. Chaque élément de la checklist est une invite à vérifier un aspect spécifique, avec des conseils pratiques sur la façon de le faire et pourquoi c'est important, ce qui en fait un guide utile aussi bien pour les développeurs expérimentés que pour les débutants. La compétence s'applique à n'importe quelle plateforme (comme Supabase, Firebase, Cloudflare, AWS, etc.) et est neutre vis-à-vis du langage de programmation ou du framework utilisé.

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/joechrisnaldy/production-readiness-skill/tree/HEAD

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Checklist de Préparation à la Production

Chaque entrée indique quoi vérifier. Appliquez ce qui correspond au stade du projet en utilisant les niveaux de stade définis dans CLAUDE.md ; si aucun n'est défini, déduisez le stade (Prototype, MVP, Production ou Scale) et indiquez-le. Lors des revues, marquez les entrées qui ne correspondent pas au stade comme non applicables pour l'instant, avec le déclencheur qui les rendrait pertinentes.

1. Sécurité et contrôle d'accès

  • Autorisation : Vérifiez les permissions côté serveur sur chaque point de terminaison et pour chaque objet accédé, et pas seulement à la connexion (empêche IDOR et BOLA). Avec Supabase, Firebase ou des backends similaires, la sécurité au niveau des lignes ou les règles de sécurité doivent être activées et testées.
  • Validation des entrées : Validez le type, la longueur, le format et la plage à chaque frontière de confiance avec une bibliothèque de schémas (Zod, Pydantic ou équivalent). La validation côté client est pour l'expérience utilisateur, jamais pour la sécurité.
  • Injection SQL : Utilisez uniquement des requêtes paramétrées ou des liaisons ORM. Autorisez une liste blanche pour les identifiants dynamiques tels que les colonnes de tri.
  • XSS : Fiez-vous à l'échappement du framework. Évitez innerHTML, dangerouslySetInnerHTML et v-html avec des données non fiables, ou nettoyez avec une bibliothèque validée telle que DOMPurify. Ajoutez une politique de sécurité du contenu.
  • CSRF : Pour les sessions basées sur les cookies, utilisez des cookies SameSite plus des jetons CSRF ou des vérifications d'origine sur les requêtes modifiant l'état. Ne modifiez jamais l'état sur GET.
  • CORS : Autorisez une liste blanche d'origines exactes. Ne reflétez jamais des origines arbitraires et n'autorisez pas de caractère générique avec des identifiants. CORS n'est pas un contrôle d'accès.
  • SSRF : Lorsque le serveur récupère des URL fournies par l'utilisateur, autorisez une liste blanche de destinations, bloquez les adresses privées, de bouclage et lien-local pour IPv4 et IPv6 (y compris les métadonnées cloud à 169.254.169.254), et revérifiez après les redirections et la résolution DNS.
  • Gestion des secrets : Chargez les secrets à partir de variables d'environnement ou d'un gestionnaire de secrets. Ils n'apparaissent jamais dans le code, les journaux, les images de conteneurs ou l'historique git, et tout ce qui a fuité doit être tourné.
  • IAM : Appliquez le moindre privilège à chaque personne, service et jeton. Utilisez des identifiants séparés par environnement et par service, et n'utilisez jamais de clés root ou admin dans les applications.
  • OAuth : Utilisez un fournisseur ou une bibliothèque éprouvé plutôt qu'une authentification personnalisée. Utilisez Authorization Code avec PKCE pour les clients navigateur et mobile, une correspondance exacte de l'URI de redirection, une validation d'état et des étendues minimales.
  • Rotation JWT : Utilisez des jetons d'accès à courte durée de vie, des jetons d'actualisation rotatifs avec détection de réutilisation, et des clés de signature tournées via des identifiants de clé (kid) et JWKS. Vérifiez toujours la signature, l'algorithme, l'émetteur, l'audience et l'expiration.
  • Sécurité des mots de passe et des sessions : Hachez les mots de passe avec Argon2id ou bcrypt. Définissez les cookies de session comme HttpOnly, Secure et SameSite. Proposez MFA là où les comptes ont de la valeur.
  • TLS : Servez HTTPS partout avec un renouvellement automatique de certificat, TLS 1.2 minimum (préférez 1.3) et HSTS. Ne désactivez jamais la vérification de certificat.
  • Chiffrement en transit : Chiffrez le trafic interne ainsi que le trafic public, y compris les connexions de service, de base de données, de cache et de file d'attente.
  • Chiffrement au repos : Chiffrez les bases de données, les disques, les sauvegardes et le stockage d'objets, avec des clés dans un KMS. Envisagez un chiffrement au niveau du champ pour les données hautement sensibles.
  • En-têtes de sécurité : Définissez Content-Security-Policy (y compris frame-ancestors contre le clickjacking), Strict-Transport-Security, X-Content-Type-Options: nosniff et Referrer-Policy.
  • WAF : Placez un pare-feu d'application web avec des ensembles de règles gérés devant les applications de production publiques.
  • Protection DDoS : Fiez-vous à la protection du fournisseur (Cloudflare, AWS Shield ou les valeurs par défaut de la plateforme) ainsi qu'aux limites de débit et aux plafonds de mise à l'échelle automatique, de sorte qu'une attaque ne puisse pas devenir une facture illimitée.
  • Sécurité de la chaîne d'approvisionnement : Exécutez des analyses de vulnérabilité des dépendances (npm audit, pip-audit, Dependabot ou similaire) dans le CI. Vérifiez que chaque nouveau paquet est réel, correctement nommé et maintenu.
  • Téléchargements de fichiers : Vérifiez le type par le contenu plutôt que par l'extension, limitez la taille, stockez dans un stockage d'objets sous des noms aléatoires et servez les fichiers privés via des URL signées à courte durée de vie.
  • Journaux d'audit : Enregistrez qui a fait quoi et quand pour les actions sensibles (événements d'authentification, modifications de permissions, exportations de données, mouvements d'argent) dans un stockage en ajout uniquement.
  • Confidentialité et PII : Collectez le minimum, sachez où vivent les données personnelles, gardez-les hors des journaux, définissez une rétention et prenez en charge la suppression et l'exportation là où des lois telles que le RGPD ou le CCPA s'appliquent.

2. Données et bases de données

  • Indexation de base de données : Indexez les colonnes utilisées dans les filtres, les jointures et les tris sur les tables qui vont grossir, y compris les clés étrangères. Évitez les index redondants qui ralentissent les écritures.
  • Optimisation des requêtes : Vérifiez les plans avec EXPLAIN pour les requêtes lentes ou fréquentes. Sélectionnez uniquement les colonnes nécessaires et évitez d'envelopper les colonnes indexées dans des fonctions à l'intérieur des clauses WHERE.
  • Requêtes N+1 : Trouvez les boucles qui interrogent une fois par élément. Remplacez-les par des jointures, un chargement eager ou un traitement par lots.
  • Pool de connexions : Dimensionnez les pools en fonction des limites de la base de données. En serverless, utilisez un pooler (PgBouncer, RDS Proxy ou le pooler du fournisseur) car chaque instance ouvre ses propres connexions.
  • Transactions : Enveloppez les écritures en plusieurs étapes qui doivent réussir ou échouer ensemble dans une seule transaction, et choisissez le niveau d'isolement délibérément.
  • Contraintes : Appliquez l'intégrité dans la base de données avec NOT NULL, UNIQUE, les clés étrangères et les contraintes CHECK. Les vérifications d'application seules perdent face aux conditions de concurrence.
  • Pagination : Paginez chaque point de terminaison de liste et chaque requête avec une taille de page plafonnée. Préférez la pagination par curseur (clé de jeu) pour les données volumineuses ou changeantes.
  • Argent et temps : Stockez l'argent sous forme d'unités mineures entières ou d'un type décimal. Stockez les horodatages en UTC et convertissez uniquement pour l'affichage.
  • Réplicas de lecture : Ajoutez-les uniquement lorsque les lectures surchargent le primaire, et gérez le décalage de réplication, en particulier lorsque les utilisateurs lisent leurs propres écritures.
  • Réplication : Sachez si elle est synchrone ou asynchrone et la quantité de données qu'un basculement peut perdre.
  • Partitionnement : Partitionnez les très grandes tables (souvent par temps) pour que les index et la maintenance restent gérables, et supprimez les anciennes données en supprimant des partitions.
  • Sharding : Traitez-le comme un dernier recours après l'indexation, la mise en cache, les réplicas et la mise à l'échelle verticale. Choisissez une clé de shard qui évite les points chauds et les requêtes cross-shard.
  • Migrations de base de données : Gardez les migrations versionnées, révisées, automatisées dans les déploiements et réversibles si possible. Pour un temps d'arrêt nul, utilisez expand et contract : ajoutez, remplissez, basculez, puis supprimez dans une version ultérieure. Sauvegardez avant les modifications destructrices.
  • Versionnement de schéma : Versionnez les contrats de données (schémas de base de données, charges utiles d'événements, schémas d'API) afin que l'ancien et le nouveau code puissent s'exécuter côte à côte pendant les déploiements.

3. Concurrence et systèmes distribués

  • Conditions de concurrence : Traquez le code de type vérifier-puis-agir (soldes, inventaire, noms d'utilisateur uniques, échange de coupons). Corrigez-le avec des mises à jour atomiques, des contraintes, des transactions ou des verrous.
  • Sécurité des threads : Synchronisez ou éliminez l'état mutable partagé entre les threads, les workers et les tâches asynchrones. Les variables globales au niveau du module sont souvent partagées entre les requêtes.
  • Verrouillage optimiste : Vérifiez une colonne de version ou un ETag lors de la mise à jour pour les enregistrements à faible contention, et renvoyez 409 ou 412 en cas de conflit.
  • Verrouillage pessimiste : Utilisez SELECT ... FOR UPDATE pour les sections critiques à forte contention, et gardez les verrous courts.
  • Impasses (Deadlocks) : Acquérez les verrous dans un ordre cohérent, gardez les transactions courtes et réessayez en cas d'erreur d'impasse.
  • Verrous distribués : Utilisez-les uniquement pour la coordination entre les processus, avec des baux qui expirent et des jetons de clôture. Préférez les contraintes de base de données ou les files d'attente lorsque celles-ci suffisent.
  • Transactions distribuées : Évitez la validation en deux phases entre les services. Gardez les limites transactionnelles à l'intérieur d'une seule base de données si possible.
  • Modèle Saga : Pour les workflows qui s'étendent sur plusieurs services, enchaînez les transactions locales avec des actions compensatoires, et rendez chaque étape idempotente.
  • Théorème CAP : Lors d'une partition réseau, un système doit choisir entre cohérence et disponibilité. Décidez par fonctionnalité : les soldes et l'inventaire ont besoin de cohérence, tandis que les flux et les compteurs peuvent tolérer le vieillissement.
  • Cohérence éventuelle : Là où elle est acceptée, concevez l'interface utilisateur et la logique pour les lectures obsolètes et faites converger les mises à jour.
  • Élection de leader : Lorsqu'exactement une instance doit agir (planificateurs, workers singleton), utilisez un bail ou une primitive de plateforme, jamais une instance codée en dur.
  • Partitions réseau : Supposons que tout appel peut échouer à mi-chemin ou réussir sans réponse. Concevez avec des délais d'attente, l'idempotence et la réconciliation.
  • Décalage d'horloge : Ne vous fiez jamais aux horloges de différentes machines pour l'ordre ou l'exactitude. Utilisez les horodatages de la base de données, les numéros de séquence ou les horloges logiques, et autorisez une petite marge dans les vérifications d'expiration des jetons.
  • Découverte de services : Résolvez les services via DNS, la plateforme ou un registre, jamais des IP codées en dur.

4. Résilience et tolérance aux pannes

  • Délais d'attente : Donnez à chaque appel sortant (HTTP, base de données, cache, file d'attente, API LLM) des délais d'attente de connexion et de requête qui s'inscrivent dans le propre délai de l'appelant.
  • Nouvelles tentatives : Ne réessayez que les échecs transitoires (délais d'attente, erreurs de connexion, 429, 502, 503, 504) sur les opérations idempotentes, avec un nombre de tentatives plafonné. Évitez de réessayer à toutes les couches à la fois, ce qui multiplie la charge.
  • Backoff exponentiel : Reculer exponentiellement avec un jitter, et respectez les en-têtes Retry-After.
  • Disjoncteurs (Circuit Breakers) : Arrêtez d'appeler une dépendance défaillante après des erreurs répétées, échouez rapidement avec un repli et sondez pour la récupération.
  • Idempotence : Donnez aux opérations qui peuvent être retentées (paiements, commandes, gestionnaires de webhooks, travaux) une clé d'idempotence ou une clé naturelle, afin que les doublons n'aient aucun effet supplémentaire.
  • Contre-pression (Backpressure) : Limitez les files d'attente, les tampons et la concurrence. En cas de surcharge, réduisez la charge ou renvoyez 429 ou 503 au lieu d'accepter un travail illimité.
  • Cloisonnement (Bulkheads) : Isolez les ressources (pools ou workers séparés) afin qu'une dépendance lente ne puisse pas tout épuiser.
  • Dégradation gracieuse : Décidez ce qui fonctionne encore lorsqu'une dépendance est en panne, comme des données en cache, un mode lecture seule ou la masquage temporaire d'une fonctionnalité.
  • Arrêt gracieux : Sur SIGTERM, arrêtez d'accepter de nouveaux travaux, terminez les requêtes et les travaux en cours, puis fermez les connexions.
  • Vérifications de santé (Health Checks) : Exposez un point de terminaison de santé peu coûteux pour l'équilibreur de charge ou la plateforme.
  • Sondes de vivacité (Liveness) et de disponibilité (Readiness) : La vivacité ne détecte qu'un processus bloqué et ne doit pas dépendre de services externes, sinon un seul problème de base de données redémarre tout. La disponibilité détermine si une instance doit recevoir du trafic et peut vérifier les dépendances.
  • Basculement (Failover) : Sachez ce qui se passe lorsque la base de données primaire, la zone ou le fournisseur tombe en panne. Automatisez-le là où la disponibilité compte, et testez-le.

5. Messagerie, travaux en arrière-plan et temps réel

  • Files d'attente de messages : Déplacez les travaux lents, pouvant être retentés ou en rafale (e-mails, traitement multimédia, appels tiers) hors du chemin de la requête dans une file d'attente avec des workers.
  • Sémantique de livraison : Supposez une livraison au moins une fois, donc les consommateurs doivent être idempotents. Ne supposez pas un ordre à moins que le système ne le garantisse par clé.
  • Files d'attente de lettres mortes (DLQ) : Acheminez les messages qui épuisent les tentatives vers une DLQ avec une alerte et un chemin de rejeu. Ne les supprimez jamais silencieusement et ne réessayez pas indéfiniment.
  • Pub/Sub : Utilisez-le pour la diffusion à plusieurs consommateurs indépendants, avec des schémas d'événements et une propriété définis.
  • Architecture pilotée par les événements : Adoptez-la lorsque le découplage vaut le coût du débogage. Traitez les événements comme des contrats versionnés et gardez les requêtes traçables à travers eux.
  • Boîte de sortie transactionnelle (Transactional Outbox) : Lorsqu'une écriture en base de données doit également publier un événement, écrivez les deux dans une seule transaction (une table outbox) et relayez de manière asynchrone, ce qui évite le problème de double écriture.
  • Tâches Cron : Rendez les tâches planifiées idempotentes, sûres à exécuter deux fois ou en chevauchement, limitées à une instance à la fois, et surveillées pour les exécutions manquées ou échouées.
  • WebSockets : Authentifiez à la connexion, envoyez des heartbeats, reconnectez-vous avec backoff et planifiez pour plusieurs instances (pub/sub partagé ou sessions persistantes).
  • Événements envoyés par le serveur (SSE) : Préférez-les aux WebSockets pour les flux unidirectionnels du serveur vers le client tels que les notifications, la progression et le streaming de jetons LLM.
  • Long Polling : Utilisez-le comme solution de repli lorsque WebSockets et SSE ne sont pas disponibles, avec des délais d'attente et une limite sur les connexions maintenues.
  • Webhooks : Pour les webhooks entrants, vérifiez les signatures (HMAC), rejetez les horodatages obsolètes pour arrêter les rejeux, accusez réception rapidement et traitez de manière asynchrone, et dédupliquez par ID d'événement. Pour les webhooks sortants, signez les charges utiles, réessayez avec backoff et versionnez les formats d'événements.

6. Trafic, edge et réseau

  • Limitation de débit (Rate Limiting) : Limitez par utilisateur, clé API et IP sur les points de terminaison publics, d'authentification et coûteux (connexion, inscription, réinitialisation de mot de passe, OTP, appels LLM). Renvoyez 429 avec Retry-After.
  • Équilibrage de charge : Répartissez le trafic entre les instances vérifiées pour la santé. Gardez les serveurs d'application sans état afin que n'importe quelle instance puisse répondre à n'importe quelle requête.
  • Proxys inverses : Terminez TLS, compressez et appliquez les limites de taille de corps et de délai d'attente au niveau du proxy. Ne faites confiance à X-Forwarded-For qu'à partir de proxys connus afin que les adresses IP des clients ne puissent pas être usurpées.
  • Passerelles API : Centralisez l'authentification, la limitation de débit, le routage et la validation lorsqu'il existe plusieurs services ou une API publique. Une application unique en a rarement besoin.
  • CDN : Servez les actifs statiques et les médias via un CDN avec des durées de vie de cache longues et des noms de fichiers hachés par contenu.
  • DNS : Abaissez les TTL avant les migrations, gérez les enregistrements comme du code si possible et attendez-vous à des délais de propagation.
  • TCP vs UDP : Par défaut, utilisez des protocoles basés sur TCP. N'utilisez UDP que pour le trafic sensible à la latence qui tolère les pertes (médias en temps réel, jeux), avec une gestion au niveau de l'application.
  • HTTP/2 & HTTP/3 : Activez-les au niveau de l'edge ou du CDN pour le multiplexage et des connexions plus rapides. C'est généralement une configuration, pas du code d'application.
  • gRPC : Utilisez-le pour les appels de service internes qui ont besoin de contrats stricts ou de streaming, avec un délai sur chaque appel. Les navigateurs ont besoin de gRPC-Web ou d'une passerelle.

7. Mise en cache

  • Mise en cache : Ne mettez en cache qu'après avoir mesuré un besoin, et définissez la clé, le TTL et l'audience de chaque cache. Ne stockez jamais de données spécifiques à un utilisateur ou dépendantes des autorisations dans un cache partagé sous une clé générique.
  • Mise en cache Edge : Définissez Cache-Control explicitement, marquez les réponses personnalisées comme private ou no-store, et utilisez stale-while-revalidate lorsque la fraîcheur est moins critique que la latence.
  • Mise en cache de requête : Utilisez-la pour les requêtes coûteuses (agrégations SQL, réponses d'API externes) avec un TTL adapté à la fraîcheur des données, pas plus long. Invalidez par événement (cache-aside) si possible ou acceptez le vieillissement.
  • Mise en cache distribuée : Utilisez Redis ou Memcached pour les données partagées entre les instances, avec des politiques d'éviction et de sérialisation, jamais pour stocker des sessions d'état côté serveur qui attachent un utilisateur à une instance.
  • Cache du navigateur : Servez les actifs immuables avec Cache-Control: public, max-age=31536000, immutable. Pour les actifs muables, utilisez no-cache, une version de cache (ETag) ou un cache busting.
  • Cache client/API : Pour les API, utilisez des en-têtes de mise en cache (ETag, Last-Modified) afin que les clients et les proxys puissent éviter de demander des ressources inchangées.
  • Mise en cache du contenu personnalisé : Ne mettez jamais en cache le contenu personnalisé dans un cache partagé, à moins que le cache ne soit partitionné par utilisateur. Incluez un jeton CSRF dans les pages mises en cache pour les utilisateurs authentifiés.

8. Performances et efficacité

  • Profiling : Profilez avant d'optimiser. Mesurez la latence du 99e percentile, la débit et l'utilisation des ressources, pas seulement la moyenne.
  • Goulots d'étranglement : Recherchez les ralentissements dans le réseau, la base de données, le calcul. Un goulot d'étranglement d'E/S a besoin d'une solution différente de celle d'un goulot d'étranglement CPU.
  • Opérations coûteuses : Identifiez et optimisez les appels API lents, les jointures volumineuses, les calculs sur de grands ensembles de données.
  • Surcharge de requêtes : Évitez d'ajouter des champs ou des appels inutiles à chaque requête. Cela s'accumule à grande échelle.
  • Parallélisme : Parallélisez les appels non dépendants entre eux, en utilisant Promise.all, asyncio.gather ou équivalent, mais limitez la concurrence pour éviter la surcharge.
  • Mise à l'échelle verticale : Améliorez la machine ou l'instance avant d'ajouter de la complexité. Parfois, l'instance la plus grande suffit.
  • Mise à l'échelle horizontale : Ajoutez des instances et répartissez le trafic. L'application doit être sans état et partager la session, le cache et les files d'attente.
  • Mise à l'échelle automatique : Utilisez la mise à l'échelle automatique basée sur le CPU, la mémoire ou les métriques personnalisées, avec des limites de min et max pour que la mise à l'échelle ne devienne pas une surprise de facture.
  • E/S par lots : Lorsque vous traitez des listes, lotissez les opérations (insertions en masse, traitements de file d'attente par lots).
  • Startup à froid : En serverless, gardez les fonctions légères, utilisez un provisionnement simultané ou des workers réservés, et distribuez les fonctions par profil de ressources.

9. API et intégrations

  • Conception API RESTful : Utilisez des noms de ressources cohérents (pluriels, en minuscules), des verbes HTTP (GET pour lire, POST pour créer, PUT/PATCH pour mettre à jour, DELETE pour supprimer) et des codes d'état (200, 201, 204, 400, 401, 403, 404, 409, 422, 429, 500).
  • Pagination API : Paginez chaque point de terminaison de liste avec des paramètres de page/taille de page ou de curseur, et incluez des métadonnées : total, page suivante, page précédente.
  • Versionnement API : Versionnez via le chemin d'URL (v1, v2) ou l'en-tête Accept. Les modifications rétrocompatibles dans une version sont correctes ; les modifications destructrices nécessitent une nouvelle version.
  • Contrats API : Documentez les API avec OpenAPI, GraphQL SDL ou gRPC protos. Utilisez la validation automatique des schémas en test.
  • Middleware API : Centralisez l'authentification, la limitation de débit, la journalisation, la gestion des erreurs et la validation dans le middleware, pas dans chaque gestionnaire.
  • Gestion des erreurs : Renvoyez des messages d'erreur cohérents et structurés (code, message, détails) et ne fuyez jamais les traces de pile ou les détails internes.
  • Intégrations tiers : Traitez les appels tiers comme des défaillances potentielles : délais d'attente, nouvelles tentatives, disjoncteurs, replis. Ne les placez pas dans le chemin critique d'une requête sauf si nécessaire.
  • Accords de niveau de service (SLA) tiers : Connaissez la disponibilité, la latence et les limites de débit de chaque dépendance. Concevez en tenant compte des pires cas.
  • Rétrocompatibilité : Les API et les intégrations doivent fonctionner avec les clients plus anciens. Ajoutez des champs comme facultatifs, ne supprimez pas les champs, utilisez des valeurs par défaut.
  • Appels d'API coûteux : Mettez en cache et lotissez les appels d'API externes ou coûteux. Surveillez leur utilisation et leurs coûts.

10. Observabilité et journalisation

  • Journalisation structurée : Utilisez une journalisation structurée (JSON) afin que les outils puissent l'analyser. Incluez un ID de requête, un ID de service, un ID de trace, un niveau, un horodatage et des champs pertinents.
  • Niveaux de journal : Utilisez debug, info, warn, error et fatal délibérément. Les journaux de débogage peuvent être verbeux ; les erreurs nécessitent une attention.
  • Journalisation des erreurs : Ne vous contentez pas de journaliser le message d'erreur. Journalisez le contexte (requête, utilisateur, ID de la ressource) et toute la trace de pile.
  • Métriques : Collectez et alertez sur l'utilisation des ressources, la latence, le débit, les taux d'erreur, la saturation (RED ou USE). Utilisez Prometheus, Datadog, CloudWatch ou équivalent.
  • Traçage distribué : Une demande unique traversant plusieurs services doit être traçable via un ID de trace partagé. Utilisez OpenTelemetry ou équivalent.
  • Alerting : Configurez des alertes sur les métriques et les journaux importants : disponibilité, haut taux d'erreur, latence élevée, utilisation des ressources.
  • Tableaux de bord : Créez des tableaux de bord pour les opérateurs et les développeurs avec des graphiques de haut niveau et des détails d'exploration.
  • Conservation des journaux : Conservez les journaux pour le débogage et les audits, mais fixez une politique de conservation pour contrôler les coûts.
  • Traçage des erreurs : Utilisez un service de suivi des erreurs pour regrouper et alerter sur les exceptions.
  • Journaux d'accès : Journalisez chaque requête avec son chemin, ses paramètres, sa méthode, le code d'état et sa durée.

11. Tests et qualité

  • Tests unitaires : Testez les fonctions et les méthodes individuelles, en particulier la logique métier, les règles de validation et les calculs.
  • Tests d'intégration : Testez les interactions avec la base de données, l'API, le cache et les services externes dans un environnement contrôlé.
  • Tests bout en bout (E2E) : Testez les parcours utilisateur complets via l'interface utilisateur ou l'API dans un environnement aussi proche que possible de la production.
  • Tests de régression : Les modifications ne doivent pas casser les fonctionnalités existantes. Automatisez les tests de régression pour les fonctionnalités critiques.
  • Couverture de code : Mesurez la couverture de code, mais ne la traitez pas comme un objectif. Concentrez-vous sur la couverture des chemins critiques, pas sur un nombre.
  • Tests de charge : Testez la capacité à gérer les pics de trafic, les charges soutenues et les patterns inattendus. Utilisez des outils comme k6, Locust, Artillery.
  • Tests de stress : Poussez le système au-delà des limites normales pour voir comment il se dégrade.
  • Tests de sécurité : Testez pour les vulnérabilités courantes (OWASP Top 10) : injections XSS, SQL, CSRF, etc.
  • Tests de faille : Simulez des pannes de services externes, une perte de réseau, une défaillance de base de données, un écrasement de disque.
  • Tests de performance : Testez la latence, le débit, l'utilisation de la mémoire, l'utilisation du CPU, le nombre de connexions ouvertes.
  • Tests de contrat : Assurez-vous que les API et les intégrations répondent à leurs contrats.
  • Intégration continue (CI) : Exécutez les tests automatiquement à chaque commit ou pull request.
  • Révisions de code : Révisez chaque modification de code pour la logique, la sécurité, les performances, la fiabilité, la maintenabilité.
  • Couverture des tests de la base de données : Testez les migrations, les contraintes, les transactions, les requêtes complexes.

12. Livraison et déploiement

  • Déploiements automatisés : Le déploiement en production est automatisé via un pipeline CI/CD, pas manuel.
  • Déploiements progressifs : Déployez progressivement : canari, bleu/vert, ou déploiement progressif (rolling).
  • Rétablissement (Rollback) : Chaque déploiement doit être facilement réversible en un clic ou une commande.
  • Déploiements sans temps d'arrêt : Les déploiements ne doivent pas interrompre le service. Utilisez des déploiements progressifs avec des migrations sans temps d'arrêt.
  • Gestion des versions : Étiquetez les versions (sémver, horodatage, ou hachage de commit) et gardez une trace de ce qui est déployé.
  • Environnement de préproduction (Staging) : Un environnement de staging doit ressembler étroitement à la production pour les tests.
  • Gestion de la configuration : La configuration est externe au code via des variables d'environnement ou un service de configuration.
  • Gestion des secrets : Les secrets sont injectés via un gestionnaire de secrets, pas codés en dur.
  • Vérifications de santé de déploiement : Après le déploiement, vérifiez que le service est sain : points de terminaison de santé, vérifications métier.
  • Surveillance du déploiement : Surveillez les métriques, les journaux et les alertes pendant la période de déploiement pour détecter les régressions.

13. Reprise après sinistre et sauvegarde

  • Sauvegardes : Sauvegardez régulièrement les bases de données, le stockage d'objets et la configuration, et testez la restauration périodiquement.
  • Réplication : Assurez-vous que les données sont répliquées vers une région ou une zone de disponibilité secondaire.
  • Basculement : Sachez ce qui se passe lorsque la base de données primaire, la zone ou le fournisseur tombe en panne. Automatisez-le là où la disponibilité compte.
  • Plan de reprise après sinistre (DRP) : Documentez et testez le plan pour restaurer le service après un sinistre majeur, avec des objectifs de temps de récupération (RTO) et de point de récupération (RPO).
  • Test de reprise : Testez le plan de reprise après sinistre périodiquement. Ne supposez pas qu'il fonctionne.
  • Sauvegardes cryptées : Les sauvegardes doivent être cryptées au repos et en transit.
  • Données de sauvegarde invariables : Empêchez la suppression ou la modification des sauvegardes une fois qu'elles sont écrites.
  • Réplication géographique : Pour une haute disponibilité, répliquez les données vers une autre région.

14. Côté client et applications mobiles

  • Minimisation : Minimisez et compressez les actifs (CSS, JS, HTML).
  • Fractionnement de code (Code Splitting) : Divisez le code en morceaux plus petits chargés à la demande.
  • Chargement différé (Lazy Loading) : Chargez les images, les composants et les modules non essentiels plus tard ou à la demande.
  • Rendu côté serveur (SSR) / Génération de site statique (SSG) : Améliorez le temps d'affichage initial et le référencement en rendant sur le serveur.
  • Mise en cache du navigateur : Utilisez les en-têtes de mise en cache du navigateur pour réduire les allers-retours.
  • Gestion de l'état : Utilisez une gestion d'état appropriée (Redux, Vuex, Context, etc.) pour l'état partagé.
  • Gestion des erreurs : Affichez des messages d'erreur conviviaux, ne vous fiez pas uniquement aux journaux de la console.
  • Indicateurs de chargement : Montrez des indicateurs de chargement ou des squelettes de chargement pendant que le contenu est chargé.
  • Accessibilité (a11y) : Utilisez la sémantique HTML, les rôles ARIA, la navigation au clavier, les contrastes de couleurs.
  • Internationalisation (i18n) : Externalisez les chaînes pour la traduction, utilisez des formats de date/d'heure/d'argent sensibles à la locale.
  • Performances mobiles : Optimisez pour les connexions lentes et les petits écrans : images plus petites, paquets plus petits, moins de allers-retours.
  • Mode hors ligne : Envisagez la prise en charge hors ligne avec les service workers ou la mise en cache locale.
  • Analytics : Ajoutez des analytics pour comprendre le comportement des utilisateurs et les métriques de performance.
  • Confidentialité : Obtenez le consentement avant de suivre les utilisateurs, en particulier sous RGPD ou CCPA.

15. Fonctionnalités LLM (si applicable)

  • Limitation de débit des LLM : Limitez les appels aux API LLM pour contrôler les coûts et la latence.
  • Journalisation des interactions LLM : Journalisez les invites et les réponses pour le débogage et la surveillance, mais évitez d'enregistrer les données sensibles.
  • Surveillance des coûts LLM : Surveillez l'utilisation de tokens et les coûts des API LLM.
  • Mise en cache des réponses LLM : Si possible, mettez en cache les réponses LLM pour les invites identiques afin de réduire les coûts et la latence.
  • Gestion des erreurs LLM : Gérez les erreurs d'API LLM avec des délais d'attente, des nouvelles tentatives, des replis, des disjoncteurs.
  • Invites préparées (Prompt Engineering) : Concevez des invites robustes avec des instructions, des exemples et des contraintes de format.
  • Test des invites : Testez les invites avec une variété d'entrées pour éviter les comportements inattendus.
  • Validation de la sortie LLM : Validez et nettoyez la sortie LLM avant de l'utiliser plus loin.
  • Sécurité des LLM : Empêchez l'injection d'invites, fuyez de données sensibles, attaque de jailbreak.
  • Évolutivité LLM : Assurez-vous que l'utilisation de LLM peut évoluer sans problèmes de performance ou de coût.
  • LLM avec fonctionnalités standard : Intégrez l'appel LLM avec les fonctionnalités système : utiliser les appels de fonction ou les capacités d'outils des LLM.
  • Surveillance de la qualité des LLM : Surveillez la qualité des réponses LLM : pertinence, exactitude, sécurité.
  • Conformité des LLM : Assurez-vous que l'utilisation de LLM est conforme aux lois et réglementations applicables.

Skills associés