O que kikita-criar-app-nestjs faz?
Inicializa um novo projeto NestJS e gera sua árvore de documentação AGENTS.md / .agents/ para que
qualquer agente de IA (Claude Code, Codex, etc.) que trabalhe no projeto posteriormente tenha uma
fonte completa e automantida da verdade.
0. Detecção de modo (sempre faça isso primeiro)
Verifique se o arquivo .agents/.kikita-scaffold.json existe no diretório alvo.
- Ausente → nova inicialização. Continue com a seção 1 abaixo, depois
plan.md. - Presente → este projeto já foi scaffoldado por esta habilidade. Siga
update.mdem vez disso — não reexecute o questionário nem refaça o scaffold.update.mdlida com a obtenção do template mais recente, diff desde o commit registrado e mesclagem de alterações nos arquivos.agents/do projeto (possivelmente personalizados).
0.5 Pré-condições (apenas para nova inicialização)
- Confirme se o diretório de trabalho está vazio ou se o usuário explicitamente deseja inicializar aqui.
- Nunca execute isso em um diretório que já tenha um projeto não relacionado sem perguntar primeiro.
1. Questionário (sempre pergunte antes de tocar no sistema de arquivos)
Siga plan.md passo a passo a partir daqui. Não pule o questionário. Quando terminar, execute
checklist.md antes de informar ao usuário que está concluído.
Pergunte em duas etapas, não como 12 perguntas jogadas de uma vez — a primeira resposta decide quais perguntas posteriores são relevantes, então perguntar todas de uma vez significa apresentar a um usuário de bot uma pergunta sobre "auth para sua API REST" que não se aplica a eles.
Etapa 1 — a pergunta ramificadora, sozinha:
- Tipo de aplicação: API REST, bot ou ambos no mesmo app?
- Se for bot (ou ambos): qual plataforma? Telegram (
nestjs-telegraf) ou Discord — e para Discord especificamente,necordé o padrão recomendado (menos código cola para satisfazer o padrão genérico evento→handler→service via DI/guards/pipes nativos do Nest), mas não é obrigatório: se o usuário quiserdiscord.jspuro (conhecimento existente da equipe, um recurso dodiscord.jsquenecordainda não encapsula), é uma escolha legítima — trate igual a "outra plataforma" abaixo, adaptando o padrão genérico manualmente em vez de obtê-lo gratuitamente. - Qualquer outra plataforma/biblioteca (nomeie — o padrão genérico de transporte de bot em
architecture/transport-adapter.mdadapta-se a ele, mas o código do adaptador concreto precisa ser escrito manualmente para qualquer coisa fora denestjs-telegraf/necord).
- Se for bot (ou ambos): qual plataforma? Telegram (
Etapa 2 — todo o resto, em lote (a pergunta 3 só é feita se a etapa 1 respondeu REST ou "ambos"; toda outra pergunta abaixo se aplica independentemente do tipo de aplicação):
- Testes: nenhum, ou unitário / e2e (Supertest) / ambos? "Ambos" também configura o Testcontainers para testes de integração que atingem uma instância real do Postgres em vez de mocks.
- Auth (pule completamente se a etapa 1 foi apenas bot): necessário ou não? Um "sim" cria um
padrão fixo e testado em batalha, não um menu — veja o bloco de scaffold de
core/auth.md: token de acesso de curta duração (5–15 min, nunca em cookie) + token de refresh em cookie httpOnly com escopo em/auth/refresh+ rotação (uso único, hash no banco) +csrf-csrfno endpoint de refresh + hash de senhaargon2id+RolesGuard. Não ofereça alternativas (sessões, JWT puro sem rotação) — este é o único padrão. - Jobs em background: BullMQ (filas Redis) ou não?
- Cache:
@nestjs/cache-manager+@keyv/redis(cache-aside) ou não? A recomendação padrão é não — adicione quando houver uma necessidade real de desempenho, não especulativamente em todo endpoint CRUD. - Uploads de arquivos: necessário ou não? Se sim, nenhuma subpergunta — o fornecedor de armazenamento (disco local em dev, qualquer bucket compatível com S3 em produção: AWS S3, MinIO, R2, Spaces) é uma variável de ambiente, não uma escolha no momento do scaffold.
- Mensageria assíncrona / eventos entre serviços: necessário ou não? Se sim, nenhuma subpergunta
sobre broker — RabbitMQ é o padrão fixo (filas de tarefas, roteamento, DLQ cobrem a grande maioria
dos casos).
architecture/messaging.mddocumenta Kafka como um caminho de migração posterior para necessidades de streaming/replay/throughput extremo, não uma opção de scaffold. - i18n: este projeto precisa de vários locais — mensagens de erro/validação REST traduzidas
e/ou respostas de bot em mais de um idioma? Se sim, nenhuma subpergunta —
nestjs-i18né a biblioteca fixa; a resolução de local difere por transporte (REST: cabeçalhoAccept-Language; bot: o campo de local por usuário da própria plataforma, nuncaAccept-Language) e ambos são cobertos emcore/i18n.md. Se não, pule — um projeto que só será executado em um idioma não precisa disso. - JSDoc/TSDoc na API pública: impor comentários de documentação obrigatórios em todo símbolo
exportado, ou pular? Isso determina se
.agents/agent-surface.mdé gerado (padrão recomendado: sim). - Política de Git: o agente pode commitar e enviar sem perguntar a cada vez, ou cada commit/push deve ser confirmado?
- Gerenciador de pacotes: npm, pnpm ou yarn? Recomendação padrão: pnpm.
- Remote Git: o usuário já tem uma URL de repositório para enviar? Se sim, registre —
git remote add origin <url>é executado logo apósgit init(vejaplan.md). Se nenhuma URL for fornecida, pule isso; o usuário configura o remote depois.
Registre cada resposta — elas orientam tanto o scaffold quanto quais arquivos de documentação são
gerados. Nunca assuma silenciosamente um padrão além do que está explicitamente fixado acima; se o
usuário pular uma pergunta, pergunte novamente para aquela. Esta habilidade é direcionada a um único
projeto NestJS, não a um monorepo/workspace Nx e não a uma topologia de microsserviços distribuídos
(vários serviços/repositórios implantáveis) — se o usuário quiser qualquer um deles, diga que esta
habilidade não cobre isso e pare, em vez de improvisar. Um broker de mensagens (veja pergunta 7) só
configura um app híbrido (app.connectMicroservice() dentro do mesmo app único) — nunca cria um
segundo serviço.
Padrões fixos — nunca pergunte sobre eles, estão bloqueados por design:
- ORM/DB: Prisma + Postgres. Nada de TypeORM (não recomendado para novos projetos), nada de Drizzle (escolha de nicho para perf/borda), nada de branch NoSQL/MongoDB na v1 desta habilidade.
- Validação:
class-validator+class-transformerna camada HTTP,ValidationPipeglobal configurado emmain.tsincondicionalmente comwhitelist,forbidNonWhitelisted,forbidUnknownValuesetransformtodostrue. Zod para validação de env/config (@nestjs/config+validate), imposto por uma regra ESLint bloqueando leituras diretas deprocess.envfora do arquivo de schema — vejatesting-and-quality.md's "Regras Mecanicamente Impostas". Campos DTO aninhados requerem ambos@ValidateNested()e@Type(() => NestedDto)— vejacode-style/dto-and-validation.md. Reuso de DTO viaPartialType/OmitType/PickTypeimportados de@nestjs/swagger, nunca@nestjs/mapped-types— bloqueado por ESLint, não apenas documentado (mesma seção). - Formato de resposta:
ClassSerializerInterceptorglobal +@Exclude()em campos DTO é o único mecanismo de serialização fixo — nunca uma entidade Prisma bruta retornada, nunca uma segunda abordagem de serialização introduzida sem um ADR. - Swagger/OpenAPI: sempre configurado para o branch REST.
- CORS: sempre configurado em
main.tspor meio de uma lista de origens permitidas baseada em env, nunca*. - Versionamento de API: Versionamento de URI do Nest (
/v1/...), fixo emarchitecture/transport-adapter.md. - Rate limiting:
@nestjs/throttlersempre instalado para REST e/ou bot, por IP para rotas REST, por user/chat-id para handlers de bot — nunca pulado como "não necessário ainda". - Logging:
nestjs-pino, sempre — logs JSON estruturados, nenhuma opção deLoggersimples oferecida. - Health checks:
@nestjs/terminus, sempre configurado, não bloqueado por questionário — duas rotas separadas,GET /health/live(apenas processo, sem verificações externas) eGET /health/ready(Prisma + qualquer dependência Redis/RabbitMQ escolhida), nunca mescladas em uma. Vejacore/health.md. - Desligamento gracioso:
app.enableShutdownHooks()sempre chamado emmain.ts— sem ele, o hookOnModuleDestroyde fechamento de conexão do Prisma nunca é acionado na reinicialização do container. - Mapeamento de erros Prisma: um
PrismaExceptionFilterglobal (APP_FILTER) mapeia códigosPrismaClientKnownRequestErrorpara a exceção HTTP Nest correspondente — um erro Prisma nunca aparece como um 500 bruto não tratado. - Geração do cliente Prisma:
package.jsonsempre recebe"postinstall": "prisma generate"— o cliente gerado está no .gitignore, então um clone fresco/CI precisa disso para compilar. - docker-compose.yml: sempre gerado (apenas dev/teste, nunca referenciado por implantação em produção) — Postgres sempre presente; Redis adicionado apenas se BullMQ e/ou cache foi escolhido (uma instância compartilhada para ambos); RabbitMQ adicionado apenas se mensageria foi escolhida.
2. Gerar
Siga plan.md. Copie arquivos de templates/ para o projeto alvo, incluindo os arquivos de ponto
(.gitignore, .gitattributes, .editorconfig, .prettierrc, .prettierignore, .nvmrc,
.vscode/extensions.json, .env.example, docker-compose.yml).
Duas coisas diferentes acontecem com as respostas do questionário, não as confunda:
- Placeholders de texto — encontre e substitua cada
{{TOKEN}}pelo valor real, não deixe nenhum para trás:{{PROJECT_NAME}},{{APP_TYPE}},{{BOT_PLATFORM}},{{TESTS}},{{GIT_POLICY}},{{PACKAGE_MANAGER}},{{NODE_VERSION}},{{DATE}}. - Portas de inclusão — tipo de aplicação, plataforma de bot, testes, auth, fila, cache, armazenamento,
mensageria, i18n e respostas de TSDoc obrigatório não preenchem um placeholder; elas decidem se um
arquivo inteiro (ou um bloco marcado com
<!-- SCAFFOLD -->dentro de um) é copiado. Uma resposta "não" significa que o arquivo/bloco é deletado, não preenchido com uma string vazia. Arquivos controlados por porta ainda devem ser vinculados deAGENTS.md/ o README relevante quando mantidos, e seus links removidos quando pulados.
3. Verificar
Execute checklist.md na íntegra antes de relatar sucesso.
Notas sobre a estrutura da documentação (leia uma vez, depois siga templates/ literalmente)
CLAUDE.mdé sempre um stub de uma linha apontando paraAGENTS.md.AGENTS.mdé o ponto de entrada obrigatório: uma lista curta "Deve Ler" mais regras inegociáveis, na raiz do projeto..agents/README.mdé um índice plano de tudo em.agents/— mantenha-o sincronizado sempre que um arquivo condicional (auth, fila, cache, armazenamento, mensageria, i18n, agent-surface) for adicionado ou pulado.- Tópicos que são genuinamente um documento curto permanecem planos em
.agents/*.md(workflow, git-policy, documentation, testing-and-quality, agent-surface, refactoring, progress). - Tópicos que se ramificam em vários documentos, ou registros por funcionalidade, recebem uma subpasta com seu
próprio hub
README.md:.agents/code-style/,.agents/architecture/,.agents/shared/,.agents/core/,.agents/decisions/. .agents/shared/README.mdregistrasrc/common/(utilitários independentes de framework — zero imports@nestjs/*— além de pipes/filters/interceptors/decorators genéricos)..agents/core/README.mdregistrasrc/core/singletons de todo o app (auth, provedor do cliente Prisma, logger, fila, cache, armazenamento, i18n — cada um com seu próprio arquivo de documentação condicional quando aquela funcionalidade foi escolhida)..agents/decisions/README.mdexplica quando um ADR curto é necessário (direção de camada, migração de broker de mensagens, mudança de estratégia de versionamento) — sempre gerado, começa sem arquivos ADR.- Todo conteúdo de arquivo rastreado — incluindo TSDoc — é apenas em Inglês. Sem cirílico, sem mojibake.
- Todos os documentos em
.agents/devem ser como os templates dekikita-create-angular-app: imperativos, curtos, com exemplos, terminando com uma lista de verificação de revisão/verificação.