¿Qué hace kikita-create-nestjs-app?
Inicializa un nuevo proyecto NestJS y genera su árbol de documentación AGENTS.md / .agents/ para que
cualquier agente de IA (Claude Code, Codex, etc.) que trabaje posteriormente en el proyecto tenga una
fuente de verdad completa y auto-mantenible.
0. Detección de modo (haz esto siempre primero)
Busca .agents/.kikita-scaffold.json en el directorio de destino.
- No existe → inicio nuevo. Continúa con la sección 1 a continuación, luego
plan.md. - Existe → este proyecto ya fue inicializado por este skill. Sigue
update.mden su lugar — no vuelvas a ejecutar el cuestionario ni a regenerar la estructura.update.mdse encarga de obtener la plantilla más reciente, comparar desde el commit registrado y fusionar los cambios en los archivos.agents/del proyecto (posiblemente personalizados).
0.5 Precondiciones (solo para inicio nuevo)
- Confirma que el directorio de trabajo esté vacío o que el usuario quiera explícitamente inicializar aquí.
- Nunca ejecutes esto contra un directorio que ya tenga un proyecto no relacionado sin preguntar primero.
1. Cuestionario (pregunta siempre antes de tocar el sistema de archivos)
Sigue plan.md paso a paso desde aquí. No te saltes el cuestionario. Cuando termines, ejecuta
checklist.md antes de informar al usuario que ha finalizado.
Pregunta en dos etapas, no como 12 preguntas vertidas de una sola vez: la primera respuesta decide cuáles de las preguntas posteriores son relevantes, por lo que preguntarlas todas de antemano significa presentar a un usuario solo de bot una pregunta de "autenticación para tu API REST" que no le aplica.
Etapa 1 — la pregunta ramificadora, sola:
- Tipo de aplicación: API REST, bot, o ambos en la misma aplicación?
- Si es bot (o ambos): ¿qué plataforma? Telegram (
nestjs-telegraf) o Discord — y para Discord específicamente,necordes la opción recomendada por defecto (menos código de conexión para satisfacer el patrón genérico evento→manejador→servicio mediante DI/guards/pipes nativos de Nest) pero no es obligatorio: si el usuario quierediscord.jssin procesar (experiencia existente del equipo, una característica dediscord.jsquenecordaún no envuelve), es una elección legítima — trátala igual que "otra plataforma" a continuación, adaptando el patrón genérico manualmente en lugar de obtenerlo gratis. - Cualquier otra plataforma/biblioteca (nómbrala — el patrón genérico de transporte de bots en
architecture/transport-adapter.mdse adapta a ella, pero el código del adaptador concreto debe escribirse a mano para cualquier cosa fuera denestjs-telegraf/necord).
- Si es bot (o ambos): ¿qué plataforma? Telegram (
Etapa 2 — todo lo demás, agrupado (la pregunta 3 solo se hace si la etapa 1 respondió REST o "ambos"; todas las demás preguntas a continuación aplican independientemente del tipo de aplicación):
- Pruebas: ninguna, o unitarias / e2e (Supertest) / ambas? "Ambas" también configura Testcontainers para pruebas de integración que golpean una instancia real de Postgres en lugar de mocks.
- Autenticación (omitir completamente si la etapa 1 fue solo bot): ¿necesaria o no? Un "sí" genera un
patrón fijo y probado, no un menú — consulta el bloque de generación de
core/auth.md: token de acceso de corta duración (5–15 min, nunca en una cookie) + token de actualización en una cookie httpOnly con ámbito/auth/refresh+ rotación (un solo uso, con hash en BD) +csrf-csrfen el endpoint de actualización + hash de contraseñas conargon2id+ unRolesGuard. No ofrezcas alternativas (sesiones, JWT simple sin rotación) — este es el único predeterminado. - Tareas en segundo plano: ¿BullMQ (colas respaldadas por Redis) o no?
- Caché: ¿
@nestjs/cache-manager+@keyv/redis(cache-aside) o no? La recomendación predeterminada es no — agrégalo cuando haya una necesidad real de rendimiento, no de forma especulativa en cada endpoint CRUD. - Subida de archivos: ¿necesaria o no? En caso afirmativo, no hay más subpreguntas: el proveedor de almacenamiento (disco local en desarrollo, cualquier bucket compatible con S3 en producción: AWS S3, MinIO, R2, Spaces) es una variable de entorno, no una elección en el momento de la generación.
- Mensajería asíncrona / eventos entre servicios: ¿necesaria o no? En caso afirmativo, tampoco hay
subpregunta sobre el broker: RabbitMQ es el predeterminado fijo (colas de tareas, enrutamiento, DLQ
cubren la gran mayoría de los casos).
architecture/messaging.mddocumenta Kafka como una ruta de migración posterior para necesidades de transmisión/reproducción/rendimiento extremo, no una opción en el momento de la generación. - i18n: ¿este proyecto necesita múltiples configuraciones regionales — mensajes de error/validación REST
traducidos y/o respuestas de bot en más de un idioma? En caso afirmativo, no hay más subpreguntas:
nestjs-i18nes la biblioteca fija; la resolución de configuración regional difiere según el transporte (REST: cabeceraAccept-Language; bot: el campo de configuración regional por usuario de la propia plataforma, nuncaAccept-Language) y ambos están cubiertos encore/i18n.md. En caso negativo, omítelo: un proyecto que solo se ejecutará en un idioma no necesita esto. - JSDoc/TSDoc en la API pública: ¿exigir comentarios de documentación obligatorios en cada símbolo
exportado, u omitirlos? Determina si se genera
.agents/agent-surface.md(recomendación predeterminada: sí). - Política de Git: ¿puede el agente confirmar y subir sin preguntar cada vez, o cada confirmación/subida debe ser confirmada?
- Gestor de paquetes: npm, pnpm o yarn? Recomendación predeterminada: pnpm.
- Repositorio Git remoto: ¿el usuario ya tiene una URL de repositorio para enviar? En caso afirmativo,
regístrala:
git remote add origin <url>se ejecuta justo después degit init(consultaplan.md). Si no se proporciona URL, omítelo; el usuario configurará el remoto más tarde.
Registra cada respuesta: determinan tanto la generación como qué archivos de documentación se crean. Nunca
asumas silenciosamente un valor predeterminado más allá de lo que está explícitamente fijado arriba; si el
usuario omite una pregunta, vuelve a preguntar por esa. Este skill se dirige a un único proyecto NestJS, no a
un monorepo/espacio de trabajo Nx ni a una topología de microservicios distribuidos (múltiples servicios/repositorios
desplegables) — si el usuario quiere cualquiera de esos, di que este skill no cubre eso y detente en lugar de
improvisar. Un broker de mensajes (consulta la pregunta 7) solo conecta una aplicación híbrida
(app.connectMicroservice() dentro de la misma aplicación única) — nunca inicia un segundo servicio.
Valores predeterminados fijos — nunca preguntes por estos, están bloqueados por diseño:
- ORM/BD: Prisma + Postgres. Sin TypeORM (no recomendado para proyectos nuevos), sin Drizzle (elección de nicho para rendimiento/borde), sin rama NoSQL/MongoDB en v1 de este skill.
- Validación:
class-validator+class-transformeren la capa HTTP,ValidationPipeglobal configurado enmain.tsincondicionalmente conwhitelist,forbidNonWhitelisted,forbidUnknownValuesytransformtodostrue. Zod para validación de entorno/configuración (@nestjs/config+validate), reforzado por una regla de ESLint que bloquea lecturas directas deprocess.envfuera del archivo de esquema — consultatesting-and-quality.md's "Reglas Mecánicamente Reforzadas". Los campos DTO anidados requieren tanto@ValidateNested()como@Type(() => NestedDto)— consultacode-style/dto-and-validation.md. La reutilización de DTO mediantePartialType/OmitType/PickTypese importa de@nestjs/swagger, nunca de@nestjs/mapped-types— bloqueado por ESLint, no solo documentado (misma sección). - Forma de respuesta: un
ClassSerializerInterceptorglobal +@Exclude()en los campos DTO es el único mecanismo de serialización fijo — nunca se devuelve una entidad Prisma sin procesar, nunca se introduce un segundo enfoque de serialización sin un ADR. - Swagger/OpenAPI: siempre configurado para la rama REST.
- CORS: siempre configurado en
main.tsmediante una lista blanca de orígenes basada en variables de entorno, nunca*. - Versionado de API: versionado de URI de Nest (
/v1/...), fijo enarchitecture/transport-adapter.md. - Límite de velocidad:
@nestjs/throttlersiempre instalado para REST y/o bot, con clave IP para rutas REST, con clave de usuario/id de chat para manejadores de bot — nunca se omite como "aún no necesario". - Registro:
nestjs-pino, siempre — registros JSON estructurados, no se ofrece opción deLoggersimple. - Comprobaciones de salud:
@nestjs/terminus, siempre configurado, no sujeto al cuestionario — dos rutas separadas,GET /health/live(solo proceso, sin comprobaciones externas) yGET /health/ready(Prisma + cualquier dependencia Redis/RabbitMQ elegida), nunca fusionadas en una. Consultacore/health.md. - Apagado graceful:
app.enableShutdownHooks()siempre llamado enmain.ts— sin ello, el hookOnModuleDestroyde cierre de conexión de Prisma nunca se dispara al reiniciar el contenedor. - Mapeo de errores de Prisma: un
PrismaExceptionFilterglobal (APP_FILTER) mapea los códigosPrismaClientKnownRequestErrora la excepción HTTP de Nest correspondiente — un error de Prisma nunca aparece como un 500 no controlado. - Generación del cliente de Prisma:
package.jsonsiempre recibe"postinstall": "prisma generate"— el cliente generado está en.gitignore, por lo que un clon nuevo/CI necesita esto para compilar. - docker-compose.yml: siempre generado (solo para desarrollo/pruebas, nunca referenciado por el despliegue en producción) — Postgres siempre presente; Redis agregado solo si se eligió BullMQ y/o caché (una instancia compartida para ambos); RabbitMQ agregado solo si se eligió mensajería.
2. Generar
Sigue plan.md. Copia los archivos de templates/ al proyecto de destino, incluidos los archivos de punto
(.gitignore, .gitattributes, .editorconfig, .prettierrc, .prettierignore, .nvmrc,
.vscode/extensions.json, .env.example, docker-compose.yml).
Dos cosas diferentes suceden con las respuestas del cuestionario, no las confundas:
- Marcadores de posición de texto — busca y reemplaza cada
{{TOKEN}}con el valor real, sin dejar ninguno:{{PROJECT_NAME}},{{APP_TYPE}},{{BOT_PLATFORM}},{{TESTS}},{{GIT_POLICY}},{{PACKAGE_MANAGER}},{{NODE_VERSION}},{{DATE}}. - Puertas de inclusión — el tipo de aplicación, plataforma de bot, pruebas, autenticación, cola, caché,
almacenamiento, mensajería, i18n y las respuestas de TSDoc obligatorio no llenan un marcador de posición;
deciden si se copia un archivo completo (o un bloque marcado con
<!-- SCAFFOLD -->dentro de uno) o no. Una respuesta "no" significa que el archivo/bloque se elimina, no se llena con una cadena vacía. Los archivos sujetos a puertas aún deben estar enlazados desdeAGENTS.md/ el README correspondiente cuando se mantienen, y sus enlaces eliminados cuando se omiten.
3. Verificar
Ejecuta checklist.md por completo antes de informar éxito.
Notas sobre la estructura de la documentación (léelo una vez, luego sigue las plantillas/ literalmente)
CLAUDE.mdes siempre un stub de una línea que apunta aAGENTS.md.AGENTS.mdes el punto de entrada obligatorio: una lista corta de "Lectura Obligatoria" más reglas no negociables, en la raíz del proyecto..agents/README.mdes un índice plano de todo lo que hay en.agents/— mantenlo sincronizado cada vez que se agregue u omita un archivo condicional (autenticación, cola, caché, almacenamiento, mensajería, i18n, agent-surface).- Los temas que son genuinamente un documento corto permanecen planos en
.agents/*.md(workflow, git-policy, documentation, testing-and-quality, agent-surface, refactoring, progress). - Los temas que se ramifican en varios documentos, o registros por característica, obtienen una subcarpeta
con su propio hub
README.md:.agents/code-style/,.agents/architecture/,.agents/shared/,.agents/core/,.agents/decisions/. .agents/shared/README.mdregistrasrc/common/(utilidades independientes del framework: cero importaciones@nestjs/*— más pipes/filtros/interceptores/decoradores genéricos)..agents/core/README.mdregistra los singletons de toda la aplicación desrc/core/(autenticación, proveedor del cliente Prisma, registrador, cola, caché, almacenamiento, i18n — cada uno con su propio archivo de documentación condicional cuando se eligió esa característica)..agents/decisions/README.mdexplica cuándo se requiere un ADR corto (dirección de capa, migración de broker de mensajes, cambio de estrategia de versionado) — siempre se genera, comienza sin archivos ADR.- Todo el contenido de los archivos rastreados — incluido TSDoc — está solo en inglés. Sin cirílico, sin mojibake.
- Todos los documentos en
.agents/deben leerse como las plantillas dekikita-create-angular-app: imperativos, cortos, respaldados por ejemplos, que terminan en una lista de verificación de revisión/verificación.