Etapa 8 — Personalização whitelabel e ajustes finais
Adiciona upload/remoção de logo e cor primária por tenant (módulo tenant-profile, armazenamento local atrás de uma interface StorageService trocável por object storage depois) e um endpoint público de tema para a tela de login carregar antes da autenticação. Revisão de segurança: Helmet e CORS explícito (extraídos para security.util.ts, reutilizado pelos testes e2e que verificam os cabeçalhos), Swagger em /docs cobrindo todos os módulos via o plugin oficial, paginação em alert_templates. Corrige um achado real: o reset de senha logava o token em texto puro desde a Etapa 2 — agora envia por e-mail de verdade. Build de produção do Docker validado (imagem sem devDependencies, app e worker rodando contra Postgres/Redis reais) e README consolidado com o processo de deploy. Fecha o backlog com um teste e2e do fluxo completo: master cria tenant → login → customer/produto → venda com parcelas → parcela paga → dashboard financeiro reflete o pagamento. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,57 @@ npm run prisma:migrate
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Deploy em produção
|
||||
|
||||
1. **Segredos**: copie `.env.example` para `.env` (ou injete as mesmas
|
||||
variáveis via secrets do orquestrador — nunca commite o `.env`) e troque
|
||||
todos os valores marcados como "changeme"/exemplo:
|
||||
`POSTGRES_PASSWORD`, as senhas de `DATABASE_URL_MASTER`/
|
||||
`DATABASE_URL_TENANT` (roles `app_master`/`app_tenant` — troque com
|
||||
`ALTER ROLE ... WITH PASSWORD '...'` no Postgres e atualize as duas
|
||||
connection strings de acordo), `JWT_SECRET` e `ENCRYPTION_KEY` (mínimo 32
|
||||
caracteres cada). Trocar `ENCRYPTION_KEY` depois que já existem segredos
|
||||
cifrados no banco (API keys, senha SMTP) invalida todos eles — só troque
|
||||
nessa hora se também for recriá-los. Configure `CORS_ORIGINS` com a(s)
|
||||
origem(ns) real(is) do frontend (nunca deixe vazio em produção se o
|
||||
frontend for acessado via browser).
|
||||
|
||||
2. **Build**: `docker compose build` (sem `docker-compose.override.yml`,
|
||||
que só se aplica automaticamente quando presente/em dev) builda a
|
||||
imagem `production` — multi-stage, sem devDependencies (`prod-deps` usa
|
||||
`npm ci --omit=dev`) — para os serviços `app` e `worker`.
|
||||
|
||||
3. **Subir os serviços**: `docker compose up -d` — sobe `postgres`/`redis`
|
||||
(com healthcheck), e só inicia `app`/`worker` depois que as duas
|
||||
dependências estiverem saudáveis (`depends_on: condition:
|
||||
service_healthy`). `app` expõe HTTP (`PORT`, default 3000) e tem
|
||||
healthcheck próprio batendo em `/health`; `worker` não expõe porta (sem
|
||||
HTTP) e roda os crons/filas do motor de alertas — ver seção própria
|
||||
abaixo. Os dois escalam de forma independente (`docker compose up -d
|
||||
--scale worker=3`, por exemplo) sem duplicar o disparo dos crons.
|
||||
|
||||
4. **Migrations, incluindo RLS**: `docker compose exec app npx prisma
|
||||
migrate deploy` aplica **todas** as migrations pendentes em ordem — as
|
||||
geradas automaticamente pelo Prisma e as manuais (RLS/policies/views,
|
||||
roles `app_master`/`app_tenant`, `security_invoker` das views de
|
||||
dashboard) são só pastas em `prisma/migrations/`, então não existe um
|
||||
passo separado "aplicar RLS": um único `migrate deploy` já cobre tudo,
|
||||
nessa mesma ordem, em qualquer ambiente novo.
|
||||
|
||||
5. **Verificação**: `curl https://<host>/health` (200,
|
||||
`{"status":"ok","database":"up"}`), `https://<host>/docs` (Swagger,
|
||||
todos os módulos documentados com o guard exigido por cada rota) e
|
||||
confira nos logs do `worker` que as duas filas (`alertas-mensalidade`/
|
||||
`alertas-cobranca`) inicializaram.
|
||||
|
||||
6. **Uploads de logo**: `docker-compose.yml` já monta um volume nomeado
|
||||
(`uploads_data:/app/uploads`) pro serviço `app`, então logos enviados via
|
||||
`POST /tenant/perfil/logo` sobrevivem a recriações do container. Trocar
|
||||
por object storage (S3 etc) numa etapa futura é só implementar
|
||||
`StorageService` (`src/common/storage/storage.service.ts`) de novo e
|
||||
trocar o provider registrado em `TenantProfileModule` — nenhum outro
|
||||
código muda.
|
||||
|
||||
## Variáveis de ambiente
|
||||
|
||||
Veja [.env.example](.env.example) — todas as chaves usadas pela aplicação e
|
||||
@@ -191,23 +242,31 @@ configuráveis via `ALERT_CRON_MENSALIDADE`/`ALERT_CRON_COBRANCA`,
|
||||
|
||||
```
|
||||
src/
|
||||
├── main.ts # processo web (HTTP)
|
||||
├── worker.ts # processo worker (crons + filas BullMQ, sem HTTP)
|
||||
├── app.module.ts # módulos do processo web
|
||||
├── config/ # ConfigModule, validação de env, PrismaService/PrismaMasterService/
|
||||
│ # PrismaTenantService, TenantContextService (mecanismo de RLS por request)
|
||||
├── worker/ # WorkerModule, AlertSchedulerService (crons), processors do BullMQ
|
||||
├── main.ts # processo web (HTTP)
|
||||
├── worker.ts # processo worker (crons + filas BullMQ, sem HTTP)
|
||||
├── app.module.ts # módulos do processo web
|
||||
├── security.util.ts # Helmet/CORS/arquivos estáticos — chamado por main.ts e por
|
||||
│ # testes e2e que verificam esses cabeçalhos
|
||||
├── common/storage/ # StorageService (interface) + LocalStorageService (Etapa 8)
|
||||
├── config/ # ConfigModule, validação de env, PrismaService/PrismaMasterService/
|
||||
│ # PrismaTenantService, TenantContextService (mecanismo de RLS por request)
|
||||
├── worker/ # WorkerModule, AlertSchedulerService (crons), processors do BullMQ
|
||||
└── modules/
|
||||
├── health/ # GET /health
|
||||
├── auth/ # login/refresh/logout/reset, guards, decorators, JwtStrategy
|
||||
└── alerts/ # CRUD de alert_templates, GET .../alertas/logs, resolver de fallback
|
||||
# e placeholders (usado pelo módulo web e pelo worker)
|
||||
├── health/ # GET /health
|
||||
├── auth/ # login/refresh/logout/reset, guards, decorators, JwtStrategy
|
||||
├── tenant-profile/ # GET/PUT/POST/DELETE /tenant/perfil (logo/cor), GET /public/tenants/:id/tema
|
||||
└── alerts/ # CRUD de alert_templates, GET .../alertas/logs, resolver de fallback
|
||||
# e placeholders (usado pelo módulo web e pelo worker)
|
||||
prisma/
|
||||
├── schema.prisma
|
||||
└── migrations/
|
||||
Etapas/ # Prompts e controle de progresso do build faseado
|
||||
Etapas/ # Prompts e controle de progresso do build faseado
|
||||
```
|
||||
|
||||
Documentação interativa de todos os endpoints (Swagger/OpenAPI, gerado via
|
||||
`@nestjs/swagger` + o plugin do `nest-cli.json` — não precisa de
|
||||
`@ApiProperty()` manual em cada DTO): `/docs` (`/docs-json` pro spec bruto).
|
||||
|
||||
## Progresso do build
|
||||
|
||||
Este projeto é construído em etapas. O estado oficial de cada etapa (o que
|
||||
|
||||
Reference in New Issue
Block a user