Template de API em NestJS com controller → service → repository, Prisma, autenticação JWT, Swagger e integração UAZAPI (WhatsApp no plano free), pronto para servir de base ao criar um repositório novo (produto, CRM, atendimento, etc.).
Desenvolvimento local (padrão): SQLite em arquivo — não exige Docker nem servidor de banco.
Produção: use PostgreSQL (Supabase, RDS, Neon, etc.); o passo a passo está abaixo.
Este projeto é pensado para ser copiado ou usado como referência ao iniciar outro repositório (por exemplo, um backend dedicado à UAZAPI e ao seu domínio de negócio).
- Crie o repositório novo (GitHub/GitLab) e copie os ficheiros, ou use este como template conforme o teu fluxo.
- No novo repo, ajusta ao mínimo:
package.json:name,description,author..env/.env.example:JWT_SECRET,UAZAPI_SYSTEM_NAME(identificador na UAZAPI),APP_PUBLIC_URL(URL pública para webhooks — em dev local costuma serhttp://localhost:3000; com túnel, a URL que o ngrok expõe).README.mddo novo projeto: nome, links e instruções específicas da tua equipa.
- Mantém a documentação técnica da UAZAPI em
docs/uazapi.mdou funde-a no README do produto, conforme preferires.
Após reset de base de dados ou mudança de DATABASE_URL, os utilizadores devem voltar a registar-se e a fazer login para que o JWT (sub) corresponda a uma linha em users antes de criarem instâncias WhatsApp (evita erro de foreign key em whatsapp_instances).
- Auth e utilizadores:
auth(register/login),users(GET /users/mecom JWT). - UAZAPI: criação/listagem/renomear/remover instâncias, QR e pareamento, desligar, enviar texto, configurar webhook, webhook público e atualização de estado. Detalhe em
docs/uazapi.md. - Prisma com migrações em
prisma/migrations/(inclui modeloWhatsappInstanceligado ao utilizador). - Prefixo global da API:
/api/v1. - Swagger:
http://localhost:3000/docs/v1. - CI (GitHub Actions): SQLite em arquivo (
prisma/ci.db),migrate deploy, lint, testes, build. - Script opcional:
scripts/ngrok-tunnel.shpara expor a API em desenvolvimento e testar webhooks com URL pública.
- Documentação completa:
docs/uazapi.md. - Variáveis: ver secção Variáveis de ambiente e
.env.example. - Webhook (exemplo):
POST {APP_PUBLIC_URL}/api/v1/webhooks/uazapi/{userId}(userId= UUID do utilizador autenticado).
-
Node.js 20 ou 22 e npm instalados.
-
Ambiente
cp .env.example .env
O padrão é
DATABASE_URL="file:./dev.db"— o arquivo é criado dentro deprisma/(caminho relativo aoschema.prisma). AjusteJWT_SECRETe, para testar WhatsApp,UAZAPI_ADMIN_TOKENeAPP_PUBLIC_URL. -
Instalar e migrar
npm ci npx prisma generate npm run prisma:migrate
Na primeira execução,
prisma migrate devaplica a migration inicial e criaprisma/dev.db. -
Subir a API
npm run start:dev
-
Testar
- Health:
http://localhost:3000/api/v1/health - Swagger:
http://localhost:3000/docs/v1
- Health:
Não é necessário Docker nem PostgreSQL instalado para esse fluxo.
| Comando | Descrição |
|---|---|
npm run start:dev |
API com reload |
npm run build |
Compila para dist/ |
npm run start:prod |
node dist/main.js (após build) |
npm test / npm run test:e2e |
Testes |
npm run prisma:migrate |
Cria/aplica migrações (dev) |
npm run prisma:deploy |
Aplica migrações versionadas (CI/prod) |
npm run prisma:studio |
Interface visual do banco |
Fluxo típico ao implementar uma feature que muda o banco:
-
Edite
prisma/schema.prisma(novosmodel, campos, índices, relações,enum, etc.). -
Gere e aplique uma migration em desenvolvimento (com
DATABASE_URLapontando para o seu banco local, ex. SQLitefile:./dev.db):npm run prisma:migrate
O Prisma compara o schema com o banco, gera SQL e cria uma pasta nova em
prisma/migrations/<timestamp>_<nome>/.
Você pode passar o nome na linha de comando (evita prompt interativo):npx prisma migrate dev --name add_orders_table
-
Regenerar o client (o
migrate devcostuma rodar o generate; se precisar):npx prisma generate
-
Versione no Git os arquivos novos/alterados em
prisma/migrations/e oschema.prisma. -
Produção / CI: só aplicar migrations já commitadas —
npm run prisma:deploy(prisma migrate deploy). Não usemigrate devem produção.
Boas práticas: um nome de migration descritivo (add_user_avatar, create_notifications); não editar SQL de migrations já aplicadas em outros ambientes; em equipe, alinhar ordem de merge para evitar conflitos em migrations/.
Só prototipando sem histórico de migration: npx prisma db push ajusta o banco ao schema, mas não cria pasta em migrations/ — útil para experimentar, depois volte a usar migrate dev para algo versionável.
O Prisma só permite um provider por schema.prisma. Hoje o template está em SQLite; abaixo está o caminho típico para Postgres (local, Supabase, RDS, etc.).
-
Um servidor PostgreSQL acessível (ex.: instância local, Supabase, Neon).
-
DATABASE_URLno formato URI, por exemplo:- Local:
postgresql://USER:SENHA@localhost:5432/NOME_DO_BANCO?schema=public - Supabase: copie em Project Settings → Database (use a URI indicada para conexão direta / session quando for rodar
migrate deploy, se o painel oferecer mais de um modo).
- Local:
Guarde prisma/dev.db ou exporte o que precisar — ao mudar de provider o fluxo abaixo não migra dados automaticamente.
Em prisma/schema.prisma, troque o datasource:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}(Os model podem permanecer os mesmos, salvo ajustes específicos de Postgres.)
# Exemplo — ajuste usuário, senha, host e banco
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/app?schema=public"As pastas em prisma/migrations/ foram geradas para SQLite; o SQL não é o mesmo. O caminho mais simples em template/projeto novo:
- Apague toda a pasta
prisma/migrations/(incluimigration_lock.tomldentro dela). - Garanta que o banco Postgres existe e que
DATABASE_URLestá correto. - Crie a baseline de migrations no Postgres:
npx prisma generate
npx prisma migrate dev --name init_postgresqlO Prisma cria prisma/migrations/…_init_postgresql/migration.sql, um novo migration_lock.toml com provider = "postgresql" e aplica no banco apontado por DATABASE_URL.
Depois disso, novas alterações de schema seguem o fluxo da secção Novas migrations (migrate dev em dev, migrate deploy em CI/prod).
npm run start:dev- Aplicar apenas migrations já commitadas (não use
migrate devem prod):
npx prisma generate
npx prisma migrate deploy
node dist/main.js- No Dockerfile deste repositório isso já está encadeado (
migrate deployantes donode); basta definirDATABASE_URL(eJWT_SECRET, etc.) no ambiente.
O workflow atual usa SQLite em arquivo. Ao padronizar o repositório em Postgres, alinhe o CI: use um service postgres, defina DATABASE_URL para localhost e mantenha o passo npx prisma migrate deploy (como no guia de serviços do GitHub Actions).
Se precisar transportar dados ou histórico complexo de SQLite para Postgres: Migrate from SQLite to PostgreSQL.
Se quiser rodar a API em container sem Postgres no Compose, o docker-compose.yml usa SQLite em volume (DATABASE_URL=file:/data/dev.db). Quem não usa Docker pode ignorar esse arquivo.
| Variável | Descrição |
|---|---|
DATABASE_URL |
SQLite: file:./dev.db (relativo a prisma/). Postgres: URI completa. |
JWT_SECRET |
Obrigatório trocar em produção. |
PORT |
Padrão 3000. |
APP_PUBLIC_URL |
URL pública desta API (webhooks UAZAPI). Ex.: http://localhost:3000 ou URL HTTPS em produção / túnel. |
UAZAPI_BASE_URL |
Base da API UAZAPI (free: https://free.uazapi.com). |
UAZAPI_ADMIN_TOKEN |
Token administrativo (painel UAZAPI). |
UAZAPI_SYSTEM_NAME |
Identificador enviado ao criar instância na UAZAPI (ajuste no novo repositório). |
UAZAPI_HTTP_TIMEOUT_MS |
Timeout HTTP (ms). |
UAZAPI_DEFAULT_EVENTS / UAZAPI_EXCLUDE_MESSAGES |
Eventos e exclusões do webhook (ver .env.example). |
UAZAPI_WEBHOOK_SECRET |
Opcional; se definido, o webhook exige o header x-uazapi-webhook-secret. |
Mais detalhes em .env.example e em docs/uazapi.md.
UNLICENSED (ajuste no package.json se precisar).