Que fait kikita-create-nestjs-app ?
Bootstrappe un nouveau projet NestJS et génère son arborescence de documentation AGENTS.md / .agents/ afin que tout agent IA (Claude Code, Codex, etc.) travaillant ensuite sur le projet dispose d'une source de vérité complète et auto-maintenable.
0. Détection du mode (toujours faire ceci en premier)
Vérifier la présence de .agents/.kikita-scaffold.json dans le répertoire cible.
- Absent → nouvelle initialisation. Continuer avec la section 1 ci-dessous, puis
plan.md. - Présent → ce projet a déjà été scaffoldé par cette compétence. Suivre
update.mdà la place — ne pas re-exécuter le questionnaire ni re-scaffolder.update.mdgère le tirage du dernier template, le diff depuis le commit enregistré et la fusion des modifications dans les fichiers.agents/(éventuellement personnalisés) du projet.
0.5 Préconditions (nouvelle initialisation uniquement)
- Vérifier que le répertoire de travail est vide ou que l'utilisateur souhaite explicitement initialiser ici.
- Ne jamais exécuter ceci sur un répertoire qui contient déjà un projet non lié sans demander au préalable.
1. Questionnaire (toujours demander avant de toucher au système de fichiers)
Suivre plan.md étape par étape à partir d'ici. Ne pas sauter le questionnaire. Une fois terminé, exécuter checklist.md avant d'informer l'utilisateur que c'est fini.
Poser les questions en deux étapes, pas 12 questions déversées en une seule fois — la première réponse détermine lesquelles des questions suivantes sont même pertinentes, donc les poser toutes d'un coup signifie présenter à un utilisateur bot-only une question "authentification pour votre API REST" qui ne s'applique pas à lui.
Étape 1 — la question de branchement, seule :
- Type d'application : API REST, bot, ou les deux dans la même application ?
- Si bot (ou les deux) : quelle plateforme ? Telegram (
nestjs-telegraf) ou Discord — et pour Discord spécifiquement,necordest la valeur par défaut recommandée (le moins de code de colle pour satisfaire le pattern générique event→handler→service via les DI/guards/pipes natifs de Nest) mais pas obligatoire : si l'utilisateur veutdiscord.jsbrut à la place (expertise existante de l'équipe, fonctionnalitédiscord.jsquenecordne wrappe pas encore), c'est un choix légitime — le traiter comme "autre plateforme" ci-dessous, en adaptant le pattern générique manuellement au lieu de l'obtenir gratuitement. - Toute autre plateforme/bibliothèque (nommez-la — le pattern de transport bot générique dans
architecture/transport-adapter.mds'y adapte, mais le code d'adaptateur concret doit être écrit manuellement pour tout ce qui est en dehors denestjs-telegraf/necord).
- Si bot (ou les deux) : quelle plateforme ? Telegram (
Étape 2 — tout le reste, groupé (la question 3 n'est posée que si l'étape 1 a répondu REST ou "les deux" ; chaque autre question ci-dessous s'applique quel que soit le type d'application) :
- Tests : aucun, ou tests unitaires / e2e (Supertest) / les deux ? "Les deux" câble aussi Testcontainers pour les tests d'intégration qui frappent une véritable instance Postgres au lieu de mocks.
- Authentification (ignorer totalement si l'étape 1 était bot-only) : nécessaire ou non ? Une réponse "oui"
scaffold un pattern fixe éprouvé au combat, pas un menu — voir le bloc de scaffold de
core/auth.md: token d'accès court (5–15 min, jamais dans un cookie) + refresh token dans un cookie httpOnly limité à/auth/refresh+ rotation (à usage unique, haché en DB) +csrf-csrfsur l'endpoint de refresh + hachage de mot de passeargon2id+ unRolesGuard. Ne pas proposer d'alternatives (sessions, JWT nu sans rotation) — c'est le seul défaut. - Jobs en arrière-plan : BullMQ (files d'attente Redis) ou non ?
- Mise en cache :
@nestjs/cache-manager+@keyv/redis(cache-aside) ou non ? La recommandation par défaut est non — l'ajouter lorsqu'il y a un réel besoin de performance, pas spéculativement sur chaque endpoint CRUD. - Téléchargements de fichiers : nécessaires ou non ? Si oui, pas de sous-question supplémentaire — le fournisseur de stockage (disque local en dev, tout bucket compatible S3 en prod : AWS S3, MinIO, R2, Spaces) est une variable d'environnement, pas un choix au moment du scaffold.
- Messagerie asynchrone / événements inter-services : nécessaires ou non ? Si oui, pas de
sous-question de courtier non plus — RabbitMQ est la valeur par défaut fixe (files de tâches,
routage, DLQ couvrent l'écrasante majorité des cas).
architecture/messaging.mddocumente Kafka comme un chemin de migration ultérieur pour les besoins de streaming/rejeu/débit extrême, pas comme une option au moment du scaffold. - i18n : ce projet a-t-il besoin de plusieurs locales — messages d'erreur/validation REST
traduits et/ou réponses de bot en plus d'une langue ? Si oui, pas de sous-question
supplémentaire —
nestjs-i18nest la bibliothèque fixe ; la résolution de locale diffère par transport (REST : en-têteAccept-Language; bot : le champ de locale par utilisateur de la plateforme elle-même, jamaisAccept-Language) et les deux sont couverts danscore/i18n.md. Si non, ignorer — un projet qui ne fonctionnera que dans une seule langue n'a pas besoin de ceci. - JSDoc/TSDoc sur l'API publique : imposer des commentaires de documentation obligatoires sur
chaque symbole exporté, ou ignorer ? Détermine si
.agents/agent-surface.mdest généré (recommandation par défaut : oui). - Politique Git : l'agent peut-il commit et push sans demander à chaque fois, ou bien chaque commit/push doit-il être confirmé ?
- Gestionnaire de paquets : npm, pnpm ou yarn ? Recommandation par défaut : pnpm.
- Dépôt distant Git : l'utilisateur a-t-il déjà une URL de dépôt vers laquelle pousser ? Si
oui, l'enregistrer —
git remote add origin <url>s'exécute juste aprèsgit init(voirplan.md). Si aucune URL n'est donnée, ignorer ; l'utilisateur câble le dépôt distant plus tard lui-même.
Enregistrer chaque réponse — elles pilotent à la fois le scaffold et les fichiers de documentation
qui sont générés. Ne jamais supposer silencieusement une valeur par défaut au-delà de ce qui est
explicitement fixé ci-dessus ; si l'utilisateur saute une question, redemander celle-ci. Cette
compétence cible un seul projet NestJS, pas un monorepo/espace de travail Nx ni une topologie de
microservices distribués (plusieurs services/dépôts déployables) — si l'utilisateur veut l'un ou
l'autre, dire que cette compétence ne couvre pas cela et s'arrêter plutôt que d'improviser. Un
courtier de messages (voir question 7) ne câble qu'une application hybride
(app.connectMicroservice() à l'intérieur de la même application unique) — il ne lance jamais un
second service.
Valeurs par défaut fixes — ne jamais demander à propos de celles-ci, elles sont verrouillées par conception :
- ORM/DB : Prisma + Postgres. Pas de TypeORM (non recommandé pour les nouveaux projets), pas de Drizzle (choix de performance/bordure de niche), pas de branche NoSQL/MongoDB dans la v1 de cette compétence.
- Validation :
class-validator+class-transformersur la couche HTTP,ValidationPipeglobal câblé dansmain.tsinconditionnellement avecwhitelist,forbidNonWhitelisted,forbidUnknownValuesettransformtoustrue. Zod pour la validation d'environnement/config (@nestjs/config+validate), appliqué par une règle ESLint bloquant la lecture directe deprocess.enven dehors du fichier de schéma — voirtesting-and-quality.md's "Règles Mécaniquement Appliquées". Les champs DTO imbriqués nécessitent à la fois@ValidateNested()et@Type(() => NestedDto)— voircode-style/dto-and-validation.md. La réutilisation de DTO viaPartialType/OmitType/PickTypeimportée de@nestjs/swagger, jamais de@nestjs/mapped-types— bloqué par ESLint, pas seulement documenté (même section). - Forme de la réponse : un
ClassSerializerInterceptorglobal +@Exclude()sur les champs DTO est le seul mécanisme de sérialisation fixe — jamais une entité Prisma brute retournée, jamais une seconde approche de sérialisation introduite sans ADR. - Swagger/OpenAPI : toujours câblé pour la branche REST.
- CORS : toujours configuré dans
main.tsvia une liste d'origines autorisées basée sur l'environnement, jamais*. - Versionnement de l'API : Nest URI Versioning (
/v1/...), fixé dansarchitecture/transport-adapter.md. - Limitation de débit :
@nestjs/throttlertoujours installé pour REST et/ou bot, par IP pour les routes REST, par utilisateur/chat-id pour les gestionnaires de bot — jamais ignoré comme "pas encore nécessaire". - Journalisation :
nestjs-pino, toujours — logs JSON structurés, pas d'optionLoggersimple proposée. - Vérifications de santé :
@nestjs/terminus, toujours câblé, pas conditionné par le questionnaire — deux routes séparées,GET /health/live(processus uniquement, pas de vérifications externes) etGET /health/ready(Prisma + toute dépendance Redis/RabbitMQ choisie), jamais fusionnées en une seule. Voircore/health.md. - Arrêt gracieux :
app.enableShutdownHooks()toujours appelé dansmain.ts— sans cela, le hookOnModuleDestroyde fermeture de connexion de Prisma ne se déclenche jamais lors du redémarrage de conteneur. - Mappage des erreurs Prisma : un
PrismaExceptionFilterglobal (APP_FILTER) mappe les codesPrismaClientKnownRequestErrorà l'exception HTTP Nest correspondante — une erreur Prisma ne remonte jamais comme un 500 non géré nu. - Génération du client Prisma :
package.jsonreçoit toujours"postinstall": "prisma generate"— le client généré est dans.gitignore, donc un clone frais/CI en a besoin pour compiler. - docker-compose.yml : toujours généré (dev/test uniquement, jamais référencé par le déploiement de prod) — Postgres toujours présent ; Redis ajouté uniquement si BullMQ et/ou le cache a été choisi (une instance partagée pour les deux) ; RabbitMQ ajouté uniquement si la messagerie a été choisie.
2. Génération
Suivre plan.md. Copier les fichiers de templates/ dans le projet cible, y compris les fichiers
point masqués ( .gitignore, .gitattributes, .editorconfig, .prettierrc, .prettierignore,
.nvmrc, .vscode/extensions.json, .env.example, docker-compose.yml).
Deux choses différentes se passent avec les réponses du questionnaire, ne pas les confondre :
- Paramètres textuels — chercher-remplacer chaque
{{TOKEN}}par la valeur réelle, n'en laisser aucun :{{PROJECT_NAME}},{{APP_TYPE}},{{BOT_PLATFORM}},{{TESTS}},{{GIT_POLICY}},{{PACKAGE_MANAGER}},{{NODE_VERSION}},{{DATE}}. - Portes d'inclusion — les réponses sur le type d'application, la plateforme de bot, les tests,
l'authentification, la file d'attente, le cache, le stockage, la messagerie, l'i18n et le TSDoc
obligatoire ne remplissent pas un paramètre ; elles décident si un fichier entier (ou un bloc marqué
<!-- SCAFFOLD -->à l'intérieur d'un fichier) est copié ou non. Une réponse "non" signifie que le fichier/bloc est supprimé, pas rempli par une chaîne vide. Les fichiers conditionnés doivent toujours être liés à partir deAGENTS.md/ du README pertinent lorsqu'ils sont conservés, et leurs liens supprimés lorsqu'ils sont ignorés.
3. Vérification
Exécuter checklist.md en entier avant de signaler le succès.
Notes sur la structure de la documentation (à lire une fois, puis suivre les templates/ à la lettre)
CLAUDE.mdest toujours un stub d'une ligne pointant versAGENTS.md.AGENTS.mdest le point d'entrée obligatoire : une courte liste "À lire absolument" plus des règles non négociables, à la racine du projet..agents/README.mdest un index plat de tout ce qui se trouve sous.agents/— le maintenir à jour à chaque fois qu'un fichier conditionnel (auth, queue, cache, storage, messaging, i18n, agent-surface) est ajouté ou ignoré.- Les sujets qui sont réellement un court document restent plats dans
.agents/*.md(workflow, git-policy, documentation, testing-and-quality, agent-surface, refactoring, progress). - Les sujets qui se ramifient en plusieurs documents, ou les registres par fonctionnalité, reçoivent
un sous-dossier avec son propre hub
README.md:.agents/code-style/,.agents/architecture/,.agents/shared/,.agents/core/,.agents/decisions/. .agents/shared/README.mdenregistresrc/common/(utilitaires sans framework — zéro import@nestjs/*— plus des pipes/filtres/intercepteurs/décorateurs génériques)..agents/core/README.mdenregistre les singletonssrc/core/à l'échelle de l'application (auth, fournisseur client Prisma, logger, queue, cache, storage, i18n — chacun avec son propre fichier de documentation conditionnel lorsque cette fonctionnalité a été choisie)..agents/decisions/README.mdexplique quand un ADR court est requis (direction de couche, migration de courtier de messages, changement de stratégie de versionnement) — toujours généré, commence sans fichiers d'ADR.- Tout le contenu des fichiers suivis — y compris TSDoc — est en anglais uniquement. Pas de cyrillique, pas de mojibake.
- Tous les documents dans
.agents/doivent se lire comme les templates dekikita-create-angular-app: impératifs, courts, avec des exemples, se terminant par une checklist de revue/vérification.