


Créez une application TypeScript full-stack avec des schémas d’API partagés par le serveur et le client
Pour créer ou modifier une application TypeScript full-stack. L’IA définit une seule fois chaque requête et réponse d’API pour les routes et les hooks client, vérifie l’authentification avant de lire les entrées, garde cohérents dépendances, cache et styles, et écrit des tests rapides.
Pour utiliser ces règles d'IA
## Gardez les dépendances entre paquets à sens unique et décidez où vit chaque état
Organisez la base de code afin que les responsabilités, le sens des dépendances et l’emplacement des états restent prévisibles à mesure que le système évolue.
### Structurez par responsabilité
- Donnez à chaque composant, hook, store, service et paquet un objectif unique et clair, et préférez composer de petites unités plutôt que d’ajouter des branches et des modes à une unité déjà complexe.
- Placez le code applicatif au-dessus des paquets réutilisables dans le graphe de dépendances ; les paquets de niveau inférieur ne doivent pas importer de modules applicatifs.
- Gardez les services isolés à l’écart des frameworks d’interface, registres, SDK de fournisseurs et moteurs d’exécution sans rapport avec eux.
- Partagez l’authentification au moyen d’une session et d’un modèle de données compatibles, au lieu de la réimplémenter pour chaque application.
### Préservez la responsabilité des types et des états
- Définissez des interfaces explicites pour les propriétés des composants, les états, les entrées de fonctions et les valeurs de retour.
- N’utilisez pas `any` ; utilisez `unknown` avec des gardes de type lorsque le type est réellement incertain.
- Conservez l’état du serveur dans la bibliothèque de gestion de l’état serveur, l’état global du client dans un store et l’état local de présentation dans le composant.
- Divisez un store complexe en modules d’implémentation et de types ; ne persistez que les états qui doivent survivre aux rechargements et sélectionnez explicitement les champs persistés.
## Utilisez les helpers et outils partagés du dépôt plutôt que des copies locales
Utilisez une chaîne d’outils canonique et des modèles d’implémentation partagés, au lieu de créer des substituts locaux.
### Appliquez des conventions de code cohérentes
- Utilisez le gestionnaire de paquets, le formateur, le linter, le vérificateur de types et les commandes d’audit choisis par le dépôt.
- Utilisez une journalisation structurée plutôt que la sortie de la console ; les wrappers de route propres à une requête doivent joindre automatiquement des identifiants de requête.
- Respectez une nomenclature et un ordre d’importation cohérents ; utilisez des imports réservés aux types, des assertions `const`, des types explicites d’éléments référencés et TSDoc plutôt que des commentaires décoratifs ou non structurés.
- Préférez les imports absolus. Créez un fichier d’agrégation uniquement lorsqu’un dossier comporte au moins 3 exports et ne réexportez pas depuis des fichiers qui ne sont pas des fichiers d’agrégation.
### Réutilisez les utilitaires éprouvés
- Utilisez des utilitaires partagés pour générer les ID, temporiser, normaliser les erreurs, extraire les messages, cloner en profondeur, filtrer les objets, tronquer et appliquer un délai progressif entre les nouvelles tentatives avec une variation aléatoire ; ne les recréez pas avec des paquets locaux ou une logique ponctuelle.
- Intégrez directement un utilitaire utilisé par 1 consommateur ; déplacez-le vers un module utilitaire lorsqu’au moins 2 fichiers en ont besoin.
- Extrayez un composant lorsqu’il dépasse environ 50 lignes, dessert au moins 2 appelants ou possède un état ou une logique ; laissez intégré un fragment purement visuel, à usage unique, de moins de 10 lignes.
## Définissez une seule fois chaque requête et réponse d’API et justifiez chaque fetch direct
Définissez chaque requête et réponse HTTP une seule fois afin que les routes et les clients ne divergent pas vers des formats d’échange incompatibles.
### Faites des contrats la source de vérité des frontières
- Conservez un module de contrat par famille de ressources, avec des schémas distincts pour les paramètres de chemin, les valeurs de requête, le corps, les en-têtes et la réponse, réunis dans un seul contrat de route.
- Exportez des schémas nommés et des alias de types d’entrée et de sortie nommés pour les clients, et réutilisez les primitives d’identifiants partagées au lieu de dériver des types d’échange ponctuels ou de redéfinir des identifiants fondés sur des chaînes.
- Autorisez les validateurs du domaine à utiliser directement la bibliothèque de schémas, mais gardez les schémas de frontière de route hors des gestionnaires de route et des clients.
### Contrôlez explicitement les exceptions
- Exigez une annotation motivée immédiatement au-dessus de tout appel direct exceptionnel à `fetch`, de toute double conversion de type, de toute lecture directe de JSON ou de toute réponse délibérément non typée.
- N’autorisez les appels directs à `fetch` que dans des cas tels que le streaming, le transfert binaire, l’envoi multipart, les URL signées, les redirections OAuth ou les origines externes.
- N’autorisez les lectures directes de JSON que pour les enveloppes ou l’analyse tolérante qui ne peut pas utiliser l’analyseur standard, et les réponses non typées que pour des données réellement opaques.
- Conservez les exceptions légitimes concernant des fichiers entiers dans une liste d’autorisation révisée au lieu de disperser des contournements ligne par ligne.
- Faites échouer un audit strict des frontières en cas de justifications manquantes, de schémas locaux aux routes, de lectures directes, d’appels à `fetch` non approuvés ou de doubles conversions de type non sûres.
## Ajoutez une route d’API et son hook client en partant du schéma
Ajoutez une fonctionnalité de frontière selon une séquence fixe afin que l’authentification, la validation, le typage des réponses et la mise en cache concordent de bout en bout.
### Suivez la séquence d’implémentation
1. Rédigez le contrat et ses types d’entrée et de sortie nommés.
2. Enveloppez la route dans le wrapper canonique de contexte de requête et de gestion des erreurs, en composant les middlewares partagés d’authentification, de limitation de débit et de contrôle d’accès au lieu de les réimplémenter pour chaque route.
3. Authentifiez et autorisez avant d’analyser les entrées non fiables, puis analysez toutes les parties de la requête à travers le contrat.
4. Renvoyez exactement la structure JSON déclarée par le schéma de réponse.
5. Ajoutez un hook client typé qui envoie et valide les données à travers le même contrat.
6. Utilisez le hook dans le composant et affichez son message d’erreur typé.
### Examinez les schémas comme des migrations
- Distinguez l’omission de `null` ; combiner une déclaration facultative et une déclaration acceptant `null` crée un troisième état et doit être intentionnel.
- Comparez chaque site d’appel d’une réponse avec le schéma de réponse déclaré.
- Définissez des bornes explicites pour les chaînes, les tableaux, les limites et les tailles, avec des erreurs descriptives propres à chaque champ.
- Traitez les schémas inconnus comme exceptionnels et documentez pourquoi la charge utile est opaque ; préférez les unions discriminées lorsque le format d’échange contient un discriminateur.
- Faites appel à une revue humaine pour la qualité sémantique ; les audits structurels ne peuvent pas détecter chaque borne trop faible ni chaque structure de réponse inexacte.
## Gardez le cache des requêtes correct après annulations et mises à jour optimistes
Rendez explicites l’annulation, la mise en cache, l’invalidation et les mises à jour optimistes, au lieu de masquer l’état serveur dans l’état du composant.
### Créez des hooks et des clés de requête stables
- Utilisez une référence lorsqu’un rappel stable doit lire l’entrée la plus récente et mettez cette référence à jour lorsque l’entrée change.
- Transmettez le signal d’annulation de chaque fonction de requête et attribuez à chaque requête une durée de fraîcheur explicite.
- Construisez des clés hiérarchiques depuis une racine, en passant par des préfixes de liste et de détail, pour une invalidation ciblée, et ne conservez les données précédentes que pour les requêtes à clé variable, pas pour les requêtes statiques.
### Réconciliez les mutations en toute sécurité
- Avant une mise à jour optimiste, annulez les requêtes concernées et enregistrez la valeur précédente du cache afin de pouvoir la restaurer en cas d’erreur.
- Réconciliez et invalidez à l’achèvement, pas seulement en cas de réussite, car la réussite comme l’échec exigent la cohérence du cache.
- Préférez l’invalidation ciblée à l’invalidation de l’arborescence entière de la ressource.
- N’ajoutez pas inutilement des méthodes ou des objets de mutation stables aux dépendances des rappels.
- Faites passer le JSON de même origine par l’utilitaire de requête typé ; les exceptions faisant directement appel à `fetch` doivent respecter la politique documentée des frontières.
## Laissez chaque composant partagé fixer son apparence et ajustez-la par des props
Traitez l’apparence partagée d’un composant comme une source de vérité unique appartenant au composant, plutôt que comme la responsabilité de chaque consommateur.
### Maintenez la présentation locale et composable
- Ne modifiez pas les styles globaux pour une fonctionnalité locale ; limitez le style aux composants.
- Utilisez l’utilitaire de classes conditionnelles du projet et la notation abrégée des dimensions au lieu de dupliquer la logique de construction des classes.
- N’utilisez les outils de variantes que lorsqu’un composant possède au moins 2 véritables variantes ; utilisez une simple classe conditionnelle pour basculer un seul état.
- Importez les composants partagés par le point d’entrée public pris en charge plutôt que par des sous-chemins internes.
- Vérifiez que les variables CSS référencées existent, car une variable non définie peut silencieusement prendre une couleur non voulue comme valeur de repli.
### Exprimez l’intention par les propriétés
- Exposez des propriétés pour les erreurs, les ornements, les libellés, les indications, l’état obligatoire et les modes de comportement ; réservez les substitutions de classes par le consommateur à la disposition et au dimensionnement plutôt qu’aux bordures, remplissages, rayons, hauteurs, couleurs ou traitements de focus canoniques.
- Utilisez des propriétés sous forme d’unions discriminées pour les modes au lieu de maintenir des composants presque identiques.
- Utilisez le wrapper canonique de champ libellé dans le corps des fenêtres modales afin que les espacements latéraux des champs s’alignent sur les en-têtes et les pieds de page.
- Supprimez les variantes obsolètes après la migration au lieu de laisser des chemins parallèles dans le système de design.
## Écrivez des tests Vitest rapides avec des mocks partagés et de fausses minuteries
Utilisez l’exécuteur de tests standard du dépôt, les fixtures globales et des modèles de temporisation déterministes.
### Isolez le comportement
- Nommez chaque test à côté de sa source en utilisant le suffixe de test standard du dépôt.
- Réutilisez les mocks globaux et les fabriques partagées, et n’en remplacez un que lorsqu’un test exige un comportement différent ; effacez l’état des mocks avant chaque test et définissez explicitement les valeurs de retour propres à chaque test.
- Remplacez par des mocks les registres lourds et les dépendances de fournisseurs lorsque le test ne les exerce pas.
- Utilisez un environnement d’exécution serveur, sauf si des API de navigateur sont nécessaires.
- Évitez les temporisateurs réels ; utilisez des temporisateurs simulés ou le plus petit délai déterministe requis par le comportement.
### Évitez les rechargements coûteux de modules
- Dans Vitest, préférez les mocks remontés avant les imports et les imports statiques.
- Ne combinez pas les réinitialisations de modules, les mocks tardifs et les imports dynamiques, et n’importez pas les implémentations réelles par `importActual` lorsque des mocks explicites suffisent.
- Gardez explicites les mocks d’authentification et de journalisation au lieu d’appeler des utilitaires qui masquent la création tardive de mocks.
- Exécutez l’audit strict des frontières de l’API avec les tests pertinents avant la revue.
## Ajoutez des intégrations sans convertir les variables avant leur résolution
Construisez les intégrations dans l’ordre des dépendances et préservez les références non résolues jusqu’à l’exécution.
### Suivez la séquence d’intégration
1. Définissez et enregistrez les outils avec des identifiants `snake_case` stables.
2. Ajoutez le bloc consommateur et enregistrez-le dans l’ordre canonique.
3. Ajoutez l’icône et les métadonnées requises.
4. N’ajoutez un déclencheur que si l’intégration en a besoin.
5. Vérifiez le comportement du service à l’aide de la documentation officielle de l’API.
### Respectez les étapes du cycle de vie
- Distinguez la configuration au moment de la sérialisation de la résolution des paramètres au moment de l’exécution.
- N’effectuez jamais de conversion de type pendant la sérialisation de valeurs non résolues ; cela peut détruire les références dynamiques.
- N’effectuez les conversions numériques et autres qu’après la résolution des variables pendant l’exécution.
- Maintenez synchronisées les métadonnées de l’outil, du bloc, du déclencheur, de l’authentification et de l’entrée de fichier.
- Exécutez le linting, les vérifications de types, les tests et les audits stricts des frontières, puis examinez les modifications finales pour vérifier la cohérence des contrats, du cache, du style et du registre.
