API REST que sustenta o ecossistema CONDIGTAL — sistema de gestão de condomínios composto por este backend + um app mobile em React Native (repo separado: gestao-condominio-app).
Originalmente escrita em Spring Boot, foi reescrita em NestJS + TypeScript mantendo o esquema de tabelas (gc_*) para preservar compatibilidade com scripts SQL legados.
- Stack
- Funcionalidades
- Arquitetura
- Quick start (Docker)
- Quick start (local)
- Estrutura do projeto
- Variáveis de ambiente
- Autenticação e autorização
- Documentação Swagger
- Scripts npm
- Migrations e seed
- Deploy em VPS
- Roadmap
| Camada | Tecnologia |
|---|---|
| Framework | NestJS 10 (TypeScript) |
| ORM | Prisma 5 |
| Banco | PostgreSQL 16 |
| Auth | JWT access + refresh + bcrypt |
| Validação | class-validator / class-transformer |
| Docs | Swagger (/api/docs) |
| Nodemailer (SMTP, com modo dry-run) | |
| Upload | Multer + storage local em disco |
| Segurança | Helmet, CORS allowlist, Throttler, refresh token rotation |
| Container | Docker multi-stage + docker-compose |
- 🔐 Auth: login, logout, refresh, forgot/reset password
- 👤 Pessoas / Usuários: CRUD, troca de senha, foto de perfil
- 🏢 Condomínios + Unidades + Ocupantes (vínculo proprietário/locatário)
- 🛡️ Roles dinâmicos por condomínio (
SINDICO_<id>,PORTEIRO_<id>,MORADOR_<id>, etc.) - 📅 Áreas comuns + turnos + reservas (aprovar/rejeitar/cancelar/concluir)
⚠️ Ocorrências com comentários e anexos- 📣 Comunicados multi-condomínio com confirmação de leitura
- 📦 Encomendas (registro/retirada)
- 👋 Visitantes (entrada/saída autorizada pelo morador)
- 📜 Contratos com fornecedores
- 🌐 Leads públicos (formulário da landing page)
┌────────────────────┐ HTTPS / JWT ┌─────────────────────┐
│ React Native App │ ─────────────────────▶ │ NestJS REST API │
│ (Android / iOS) │ │ (este repo) │
└────────────────────┘ └──────────┬──────────┘
│ Prisma
▼
┌─────────────────────┐
│ PostgreSQL 16 │
└─────────────────────┘
/api/*prefixo global (configurável via env).- Filtro global de exceções traduz erros do Prisma (
P2002,P2025, etc.) para HTTP semântico. - Guard global JWT — endpoints públicos marcados com
@Public(). - Guard de roles parametrizado por condomínio:
@Roles({ papel: 'SINDICO', condominioParam: 'id' }).
Recomendado para WSL/Linux/macOS — sobe API + Postgres com um comando.
git clone https://github.com/GabrielAAS28/api-gestao-condominio
cd api-gestao-condominio
# 1. copia o template de env
cp .env.example .env
# edite .env conforme sua máquina (em especial JWT_*_SECRET)
# 2. sobe os serviços
docker compose up -d
# 3. aplica migrations + seed inicial
docker compose exec api npx prisma migrate deploy
docker compose exec api npx prisma db seed
# 4. logs
docker compose logs -f apiAPI disponível em http://localhost:3000/api, Swagger em http://localhost:3000/api/docs.
docker compose down # parar
docker compose down -v # parar e apagar volumes (zera o banco)
docker compose exec api sh # shell dentro do container
docker compose exec postgres psql -U admin -d condigtal_devSem Docker, com Postgres rodando direto na máquina:
# 1. instalar deps
npm install
# 2. copiar e editar .env
cp .env.example .env
# 3. gerar Prisma Client + aplicar schema
npm run prisma:generate
npm run prisma:migrate
# 4. seed
npm run prisma:seed
# 5. dev server (watch)
npm run start:devsrc/
├── main.ts # bootstrap (helmet, swagger, validation pipe, CORS)
├── app.module.ts # módulos globais e features
├── config/ # loader das envs
├── common/
│ ├── prisma/ # PrismaService global
│ ├── decorators/ # @Public, @CurrentUser, @Roles, @GlobalAdminOnly
│ ├── guards/ # JwtAuthGuard, RolesGuard
│ └── filters/ # HttpExceptionFilter (mapeia erros Prisma)
├── shared/
│ ├── email/ # EmailService (nodemailer)
│ └── storage/ # StorageService (uploads em disco)
└── modules/
├── auth/ # login, refresh, logout, forgot/reset password
├── pessoas/
├── condominios/
├── unidades/
├── usuario-condominio/ # papéis dinâmicos por condomínio
├── ocupantes/
├── ocorrencias/ # CRUD + comentários + anexos
├── comunicados/ # multi-condomínio + anexos + confirmação de leitura
├── encomendas/ # PK BigInt
├── visitantes/
├── areas-comuns/ # com turnos
├── reservas/ # aprovar/rejeitar/cancelar/concluir
├── contratos/
└── leads/ # endpoint público para landing page
prisma/
├── schema.prisma # data model (mantém naming gc_*)
├── seed.ts # seed inicial (admin global, etc.)
└── run-seed.js # bootstrap para rodar seed em prod
uploads/ # storage local (volume persistido em prod)
Use .env.example como base. Resumo:
| Variável | Default | Descrição |
|---|---|---|
NODE_ENV |
development |
— |
PORT |
3000 |
Porta do HTTP server |
DATABASE_URL |
— | URL Postgres |
JWT_ACCESS_SECRET |
— | obrigatório — openssl rand -hex 32 |
JWT_ACCESS_EXPIRES_IN |
15m |
TTL do access token |
JWT_REFRESH_SECRET |
— | obrigatório — separado do access |
JWT_REFRESH_EXPIRES_IN |
7d |
TTL do refresh token |
CORS_ORIGINS |
* |
CSV de origens permitidas |
MAIL_HOST/PORT/SECURE/USER/PASSWORD |
— | SMTP — sem credenciais entra em modo dry-run |
UPLOAD_DIR |
./uploads |
Storage local |
MAX_FILE_SIZE_MB |
10 |
Limite de upload |
PASSWORD_RESET_TTL_HOURS |
2 |
Validade do token de reset |
PASSWORD_RESET_BASE_URL |
— | URL do frontend que recebe o token |
LEAD_NOTIFICATION_EMAILS |
— | Destinatários do POST /api/leads (CSV) |
⚠️ Nunca comite o.envreal — apenas.env.example. O.gitignorejá está configurado para isso.
POST /api/auth/login
Content-Type: application/json
{ "email": "admin@condigtal.com", "senha": "123456" }Resposta:
{
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi...",
"usuario": { "pesCod": 1, "pesNome": "...", "roles": ["ROLE_SINDICO_1"], "isGlobalAdmin": false }
}POST /api/auth/refresh
{ "refreshToken": "..." }O servidor faz rotação do refresh token (revoga o atual e emite outro).
A claim roles carrega papéis no formato ROLE_<PAPEL>_<conCod>. Ex.: ROLE_SINDICO_3 = síndico do condomínio 3. Use:
@Roles({ papel: 'SINDICO', condominioParam: 'id' })
@Get(':id/...')
metodo(@Param('id') conCod: number) { /* ... */ }@GlobalAdminOnly() permite acesso irrestrito a quem tem pesIsGlobalAdmin = true.
Após subir a API, acesse:
http://localhost:3000/api/docs
Cole o accessToken no botão Authorize para testar endpoints autenticados.
| Comando | O que faz |
|---|---|
npm run start:dev |
Watch mode |
npm run start:prod |
Roda dist/main.js |
npm run build |
Compila TypeScript |
npm run prisma:generate |
Gera Prisma Client |
npm run prisma:migrate |
Cria nova migration (dev) |
npm run prisma:migrate:deploy |
Aplica migrations (prod) |
npm run prisma:studio |
UI gráfica do Prisma |
npm run prisma:seed |
Roda prisma/seed.ts |
npm run db:reset |
destrutivo — recria schema do zero |
npm run lint |
ESLint + autofix |
npm run format |
Prettier |
# Criar nova migration durante desenvolvimento
npm run prisma:migrate -- --name add_alguma_coisa
# Aplicar em produção (não cria nova, só executa as existentes)
npm run prisma:migrate:deploy
# Seed inicial (admin global e dados-base)
npm run prisma:seedPara popular o banco com dados de simulação realistas (condomínios, pessoas, unidades, áreas comuns, reservas, etc.), use o script sql/seed-completo.sql do app mobile:
psql -h localhost -U admin -d condigtal_dev \
-f ../gestao-condominio-app/sql/seed-completo.sqlVeja o passo-a-passo completo em DEPLOY-VPS.md:
- Provisionar VPS (Hetzner, DigitalOcean, etc.)
- Setup do servidor (usuário não-root, firewall, Docker)
- Clone do repo, configurar
.envde produção docker compose up -d --build- Migrations + seed
- Reverse proxy (Nginx/Caddy) + HTTPS
- Módulo financeiro (cobranças automáticas, integração Pix/Boleto)
- Push notifications (FCM/APNs) integradas com eventos de reserva
- Audit log
- Storage S3-compatible
- Testes E2E (Jest + Supertest)
Este software é um produto comercial.
Copyright (c) 2025 Horizon AJ Soluções Digitais Ltda. Todos os direitos reservados.