4. Stack · versão 2.0.0
Ferramentas padrão
Todo projeto precisa das mesmas coisas fora do produto: subir o banco local, fazer backup antes de uma migration arriscada, restaurar para investigar, mandar um dump para outra máquina, provar que o e-mail e o armazenamento funcionam, gerar os PDFs das ADRs. Cada projeto que escreveu isso sozinho chegou a uma versão diferente, e as melhores ideias ficaram presas no projeto onde nasceram.
Este capítulo fixa o kit padrão: os comandos, o que cada um garante e de onde vem. O kit mora nos modelos de projeto do jhowdev (Vazio, Manifesto e Monorepo, ver Como usar) e chega a um projeto novo junto com esta pasta. Melhorar uma ferramenta é uma ADR no jhowdev, e os próximos projetos já nascem com a versão nova; levar a melhoria a um projeto antigo é uma ADR daquele projeto.
Princípios do kit
- Só Node e bash, sem dependência. O kit funciona em qualquer stack (o modelo Manifesto não tem app) e não quebra quando o app troca uma biblioteca. A prova do armazenamento assina o pedido S3 sozinha; a do e-mail fala SMTP sozinha.
- Docker recomendado, Podman também. O banco local e as ferramentas do Postgres rodam no
contêiner quando ele está de pé: nada a instalar, e a versão do
pg_dumpé a do servidor. O kit usa o que houver na máquina: o Docker primeiro (já vem instalado nos espaços do Gestor), o Podman quando não há Docker — odockerque só emula o Podman conta como Podman —, eCONTAINER_ENGINE(dockeroupodman) eCOMPOSE_TOOL(dockeroupodman-compose) forçam um. O pacote de produção (--producao) continua Podman sem root com systemd. - Falhar alto. Um backup que falha sai com erro e apaga o arquivo vazio; um compartilhamento que não sobe mostra o log em vez da senha; uma restauração que falharia no meio não começa.
- O caminho seguro é o padrão. Restaurar vai para um banco separado; por cima do banco vivo
só com
--into-live --force. O compartilhamento de backups tem senha sorteada e se derruba com um comando. - Portas do projeto. Cada projeto tem as suas portas locais, derivadas do nome, para que dois projetos na mesma máquina não disputem a 5432 e a 3000. Todas continuam trocáveis por variável.
- Testado. O kit tem testes sem rede (
pnpm kit:test), e o jhowdev prova os modelos inteiros (instalação, build, backup e restauração de verdade) antes de cada mudança.
Os comandos
| Comando | O que faz | Modelos |
|---|---|---|
pnpm run init | Confere as ferramentas, cria cada .env.local a partir do .env.example (sorteando os segredos marcados __GERAR__, nunca sobrescrevendo) e, com --git, o repositório (main + develop) | Manifesto, Monorepo |
pnpm db:start · db:stop · db:logs · db:down | O Postgres local do compose.yml (docker compose, ou podman-compose) | Manifesto, Monorepo |
pnpm db:psql [--banco rótulo] [--db nome] | Abre o psql no contêiner, com a URL do projeto | Manifesto, Monorepo |
pnpm db:backup [--keep N] [--only rótulo] | Um dump (formato custom) por banco de BACKUP_DATABASES em .backups/; dump falho ou vazio é apagado e o comando sai com erro; --keep mantém os N mais novos de cada banco, só depois de um dump bom | Manifesto, Monorepo |
pnpm db:restore <arquivo> [--db nome] [--into-live --force] | Restaura num banco separado (<banco>_restore, recriado); por cima do vivo só com confirmação, numa transação só (tudo ou nada) | Manifesto, Monorepo |
pnpm backup:serve · --stop | Compartilha .backups/ pela rede num nginx com senha, confere a porta antes, testa a própria URL antes de mostrar a senha, mostra os IPs reais e as dicas de firewall; --stop derruba | Manifesto, Monorepo |
pnpm storage:up · storage:check | MinIO local com bucket privado; a prova de ponta a ponta do S3 (grava, lê, confere e apaga um objeto) com a configuração do app | Manifesto, Monorepo |
pnpm mail:up · mail:check <e-mail> | Mailpit local (nenhuma mensagem sai para a internet); a prova do SMTP (TLS, autenticação e envio) com a configuração do app | Manifesto, Monorepo |
pnpm adr:pdf <NNN-slug> · pnpm pdf | Os PDFs de uma ADR e do Manifesto, com a marca do projeto num arquivo só (scripts/marca.mjs), ver Relatórios e PDF | Manifesto, Monorepo |
pnpm manifesto:pull [--versao X.Y.Z] · manifesto:check | Traz a versão nova do Manifesto, ou uma versão publicada pela etiqueta (revisar e commitar); confere links e versão | Manifesto, Monorepo |
pnpm dev · pnpm start | O app na porta do projeto, em qualquer shell, com prisma generate antes do next dev | Monorepo |
pnpm db:migrate · db:deploy · db:seed · db:studio | Prisma; o Studio numa porta fixa do projeto | Monorepo |
pnpm openapi | Regera os tipos do contrato; um teste reprova tipos desatualizados | Monorepo |
pnpm smoke · pnpm auth:sweep | Contra o app no ar: o smoke por domínio e a varredura de acesso, que chama toda operação do contrato como anônimo e como cada papel e julga pela porta declarada | Monorepo |
pnpm prod:validate | O kit de produção opcional: ensaia a produção inteira na máquina (deploy com volta automática, backup cifrado, restauração conferida, systemd) e apaga tudo | Monorepo com produção |
Vários bancos entram no backup por variável, sem editar o script:
BACKUP_DATABASES="app=DATABASE_URL radar=RADAR_DATABASE_URL" (rótulo = variável com a URL). As
URLs vêm do ambiente ou dos .env* do projeto, lendo só a linha de cada uma.
O kit de produção (opcional)
Para quem publica num servidor próprio, o modelo Monorepo com --producao traz deploy/<projeto>/
e compose.prod.yml: a imagem do app construída no servidor, o Postgres sem porta publicada, um
deploy.sh que faz backup, roda as migrations antes de trocar o app e volta sozinho se o
health não responder, o backup diário cifrado com age para um destino S3 externo (com
manifesto e conferência na restauração), as unidades do systemd e a validação local completa. O
pacote não tem proxy: HTTPS e domínio são do proxy do servidor. As regras de deploy estão em
Deploy.
Gerar um projeto
No jhowdev:
pnpm boilerplate:build <vazio|manifesto|monorepo> <destino> --nome "Meu Projeto" --slug meu-projeto \ [--autor "Nome <email>"] [--descricao "..."] [--producao] [--git]O projeto nasce com esta pasta na versão em vigor, a ADR 001 de fundação preenchida, as instruções
para a IA (CLAUDE.md e AGENTS.md), a .secrets/ padrão e o kit. A ADR 001 é a de fundação.