--- alwaysApply: true --- # Code quality ## Introduction L’objectif est de transformer une liste de principes en consignes opérationnelles, non ambiguës, applicables par une IA de développement TypeScript. Les règles ci-dessous visent une qualité d’ingénierie élevée, avec une forte exigence de maintenabilité, de cohérence, de traçabilité des erreurs et de non-duplication. Elles proscrivent explicitement les raccourcis destinés à faciliter le travail de l’IA, sans pour autant imposer une optimisation prématurée. ## Consignes de développement TypeScript pour une IA de production ### Préambule Ces consignes priment sur toute recherche de rapidité d’implémentation. Le code produit doit être maintenable, idiomatique TypeScript, conforme aux règles de qualité et de linting du dépôt, et conçu pour évoluer sans duplication. Toute ambiguïté doit être levée par l’analyse du code existant et de l’architecture avant d’écrire de nouvelles lignes de code. ### Règles de conformité TypeScript et de qualité Aucune règle de lint, de formatage, de compilation ou de qualité TypeScript ne doit être contournée, désactivée, ignorée ou neutralisée, y compris de manière locale. Sont interdits, sauf s’ils sont déjà présents et imposés par le projet, et uniquement après justification technique explicite et alignement strict avec les règles existantes : * `ts-ignore` * `ts-nocheck` * `eslint-disable` global ou ciblé * usage de `any` non justifié * cast destructif ou non sûr * suppression d’erreurs de type par assertions hasardeuses Toute évolution doit conserver une compilation stricte si le projet est en mode strict et ne doit jamais dégrader le niveau de typage. Le code doit respecter les conventions TypeScript du dépôt : organisation des modules, règles d’export, structure des types, conventions de nommage, modificateurs d’accès, usage de `readonly`, immutabilité lorsqu’elle constitue la norme du projet. ### Analyse préalable obligatoire et arbre des fichiers Avant toute implémentation, une phase d’analyse est obligatoire et doit produire une représentation de l’arbre des fichiers pertinents. Cette représentation sert à identifier : * les modules déjà disponibles * les points d’extension existants * les abstractions en place * les conventions d’architecture * les zones attendues de factorisation L’arbre doit être orienté compréhension du code existant. Il inclut les répertoires et fichiers directement liés à la fonctionnalité visée, leurs dépendances proches, ainsi que les couches d’infrastructure concernées, notamment la journalisation, la gestion des erreurs et la configuration. Aucun code nouveau ne doit être écrit tant que cette cartographie minimale n’a pas été produite et exploitée pour éviter toute duplication. ### Non-duplication et réutilisation systématique Toute logique nouvelle déclenche une vérification explicite de réutilisation possible dans le code existant. Sont considérés comme duplication à éviter : * copier-coller de blocs * variations mineures d’une même fonction * traitements parallèles de cas similaires * conversions de types répétées * mappings répétés * gestion d’erreurs répétée * validations répétées * constructions d’objets redondantes Si un comportement est récurrent, il doit être refactoré dans une abstraction partagée : fonction utilitaire ciblée, service, composant, stratégie, adaptateur ou classe de base, selon l’architecture. Toute extraction doit préserver la lisibilité et la cohésion, sans créer d’utilitaires génériques sans responsabilité claire. Une réutilisation ne doit ni introduire de dépendance circulaire ni dégrader la modularité. ### Généricité et isolation des exceptions sans duplication Le comportement par défaut doit être modélisé de façon générique. Les cas particuliers doivent être isolés dans des unités dédiées, sans répliquer le flux principal. Les exceptions métier ou techniques doivent être représentées par : * des types d’erreurs explicites * des branches clairement identifiées * des stratégies remplaçables ou des adaptateurs selon le besoin Les variations doivent être injectées par inversion de dépendance plutôt que codées sous forme de conditions dispersées. La règle est de minimiser le nombre d’endroits où un cas particulier est connu, idéalement un seul point de spécialisation. ### Design patterns et héritage Les patterns doivent être employés uniquement lorsqu’ils clarifient le découpage et réduisent effectivement la duplication. Les patterns attendus selon le contexte incluent notamment : * Factory et Abstract Factory pour instancier selon le contexte sans cascade de conditions * Strategy pour encapsuler des variations comportementales * Template Method pour définir un squelette d’algorithme stable avec points d’extension * Adapter pour interfacer une dépendance externe sans contaminer le domaine * Decorator pour enrichir un comportement sans abus d’héritage * Command pour formaliser des actions et leurs paramètres * Repository ou Gateway pour l’accès aux données ou services externes L’héritage est autorisé lorsqu’il représente une relation stable de type est-un, avec un contrat clair, et qu’il évite une duplication réelle. Il est interdit d’utiliser l’héritage pour partager des détails d’implémentation instables ou pour créer une hiérarchie artificielle. La composition est privilégiée lorsque les variations sont nombreuses ou lorsque des comportements combinables sont requis. Toute hiérarchie doit rester courte, compréhensible, testable, et ne pas masquer les dépendances. ### Gestion des erreurs, traçabilité et journalisation Tout cas d’erreur doit être journalisé. Sont inclus : * erreurs de validation * erreurs d’entrée-sortie * erreurs réseau * erreurs de parsing * états impossibles * erreurs de dépendances externes * timeouts * conflits * violations d’invariants La journalisation doit être structurée et inclure le niveau, le contexte, les identifiants pertinents, la cause, la stack lorsque disponible, et uniquement des données non sensibles. Les messages doivent permettre un diagnostic en production sans reproduction systématique. Aucune erreur ne doit être ignorée silencieusement. Les erreurs doivent remonter avec un type explicite et, si nécessaire, être enrichies par un contexte supplémentaire sans perdre la cause originelle. Les logs doivent respecter les conventions du projet, notamment l’usage d’un logger centralisé, les mécanismes de corrélation et les formats imposés. L’usage direct de `console.log` est interdit si un système de journalisation est déjà en place. ### Interdiction de fallback Aucun mécanisme de fallback implicite ne doit être introduit. Sont considérés comme fallback interdits : * l’utilisation de valeurs par défaut pour masquer une erreur * l’attrapage d’une erreur suivi d’une poursuite silencieuse * le déclenchement d’une voie alternative non explicitement spécifiée * toute dégradation silencieuse de la qualité, de la sécurité ou de la cohérence Si un comportement alternatif est requis fonctionnellement, il doit être explicitement défini comme un chemin nominal, avec des conditions d’activation claires, un typage explicite et une observabilité complète. En l’absence de spécification explicite d’alternative, l’erreur doit être remontée et journalisée. ### Interdiction de facilités pour l’IA et anti-optimisations artificielles Aucune implémentation ne doit être simplifiée pour satisfaire uniquement la compilation ou un cas minimal. Sont interdits : * stubs durables * hacks temporaires laissés en place * branches mortes * TODO structurants non résolus * implémentations partielles non signalées * comportements best effort non spécifiés L’optimisation pour l’IA elle-même est interdite. Le code ne doit pas être réorganisé pour faciliter la génération automatique au détriment de la cohérence du projet. L’optimisation de performance n’est pas un objectif par défaut. Elle n’est permise que si un goulot est identifié, mesurable, documenté, et si l’amélioration ne dégrade ni la clarté ni la sécurité. ### Tests Aucun test ad hoc ne doit être ajouté. Sont considérés comme ad hoc : * tests écrits pour forcer un comportement non contractuel * tests dupliquant la logique de production * tests utilisant des mocks excessifs pour faire passer un scénario * tests ne respectant pas la stratégie existante du projet Si le projet dispose d’une stratégie de tests, elle doit être strictement respectée. Si une couverture supplémentaire est nécessaire, elle doit s’inscrire dans les patterns de tests existants, avec les fixtures, helpers et conventions en place, sans introduire une nouvelle infrastructure. En l’absence de tests pour la zone concernée, aucune approche improvisée ne doit être introduite. Les points de vérification attendus peuvent être documentés, mais l’implémentation doit s’arrêter au code de production, sauf instruction contraire. ### Processus de modification du code Toute modification doit être minimale en surface et maximale en cohérence. Les changements doivent être localisés aux endroits architecturalement pertinents, sans dispersion. L’architecture en couches du projet doit être respectée, qu’il s’agisse du domaine, de l’application, de l’infrastructure ou de la présentation. Toute nouvelle dépendance doit être justifiée et alignée avec le socle existant. Aucune bibliothèque ne doit être introduite si une capacité équivalente existe déjà dans le projet, sauf contrainte documentée. Les noms, interfaces, types et contrats doivent être stables, explicites et orientés intention. ### Documentation et contrats Les fonctions publiques, classes et modules introduits doivent être auto-descriptifs par leur nommage et leur typage. Les commentaires ne doivent pas répéter le code. Ils doivent expliciter : * les invariants * les hypothèses * les contrats * les cas limites * les raisons d’un choix de conception Les invariants critiques doivent être vérifiés explicitement. En cas de violation, une erreur typée et journalisée doit être levée. Les interfaces doivent éviter les paramètres optionnels fourre-tout. Les objets de configuration typés sont préférés, avec des champs requis ou optionnels clairement justifiés. ### Critères d’acceptation implicites Le code final doit : * compiler sans contournement * respecter le linting sans suppression * réduire, et non augmenter, la duplication * introduire des abstractions justifiées et localisées * isoler les cas particuliers sans répliquer le flux principal * être observable en erreur via des logs structurés * ne contenir aucun fallback implicite * ne pas introduire de tests ad hoc ## Conclusion Ces consignes constituent un cadre de production strict. Elles imposent une analyse préalable via un arbre des fichiers, un typage TypeScript sans contournement, une non-duplication systématique, une architecture fondée sur des abstractions pertinentes, l’usage raisonné de patterns, une journalisation exhaustive des erreurs et un refus explicite des fallbacks implicites. Appliquées rigoureusement, elles conduisent à un code TypeScript robuste, évolutif et cohérent avec un référentiel de qualité de haut niveau. ## Analytics * Ne pas mettre d'analytics * Statistiques profil : pas de vues/paiements/revenus par article, agrégats et affichage ## Cache * Pas de mémorisation, pas de cache ## Accessibilité * ARIA * clavier * contraste