Files
SeConectai_Vendas/Etapas/05-painel-tenant-customers-produtos.md
2026-08-14 17:35:24 -03:00

70 lines
3.3 KiB
Markdown

# Etapa 5/8 — Painel Tenant: Clientes, Produtos e Serviços
## Contexto do projeto
Continuação do **SeConectai Vendas**. Já existem: setup, auth com RLS,
painel master (tenants/planos/faturas), e integrações de WhatsApp/e-mail.
Esta etapa é o núcleo operacional do **painel do tenant**: cadastro dos
clientes dele (empresas que ele atende) e do catálogo de produtos e
serviços que ele vende. Todos os endpoints usam `TenantGuard` — o
`tenant_id` vem sempre do token, nunca de input do usuário.
## Tarefas
1. **Módulo `customers` (`src/modules/customers/`)**
- CRUD completo (`GET/POST/PUT/DELETE /tenant/customers`), com
`TenantGuard`.
- Campos obrigatórios: `razao_social`. Demais opcionais conforme
schema (`documento`, `email`, `telefone_whatsapp`, endereço etc).
- Validar `documento` como CPF ou CNPJ (formato, não precisa validar
dígito verificador na primeira versão — deixar comentário no código
indicando que pode evoluir).
- `GET /tenant/customers` — listagem com busca por nome/documento,
filtro por `ativo`, paginação.
- Respeitar `limite_customers` do plano do tenant (bloquear criação
além do limite, com mensagem clara).
- Soft delete: `DELETE` não remove a linha, apenas seta `ativo=false`
(histórico de vendas depende desses registros).
2. **Submódulo `customer_contacts`**
- CRUD aninhado em `customers` (`/tenant/customers/:customerId/contatos`).
- Regra: apenas um contato pode ser `principal=true` por customer —
ao marcar um novo como principal, desmarcar o anterior
automaticamente (numa transação).
3. **Módulo `products_services` (`src/modules/products/`)**
- CRUD completo (`GET/POST/PUT/DELETE /tenant/produtos`), com
`TenantGuard`.
- `tipo` obrigatório (`produto` ou `servico`); `valor_venda`
obrigatório e > 0.
- `sku` único por tenant quando informado (respeitar constraint do
banco, retornar erro 409 amigável em caso de conflito).
- `GET /tenant/produtos` — listagem com filtro por `tipo`, `ativo`,
busca por nome/sku.
- Soft delete igual a customers (`ativo=false`) — produto usado em
venda antiga não pode sumir do histórico.
4. **Testes de RLS aplicados a esta etapa**
- Confirmar (teste automatizado) que um tenant não consegue, por
nenhum endpoint criado aqui, ler/editar/excluir customer ou produto
de outro tenant — mesmo sabendo o UUID exato do registro alheio
(deve retornar 404, não 403, para não vazar existência do recurso).
## Critérios de aceite
- [ ] CRUD de customers funcional, com soft delete e busca
- [ ] Criar customer além do `limite_customers` do plano retorna erro
claro
- [ ] CRUD de contatos aninhado funciona, e a regra de contato principal
único é respeitada
- [ ] CRUD de produtos/serviços funcional, com soft delete e busca
- [ ] SKU duplicado no mesmo tenant retorna erro 409 amigável; SKU igual
em tenants diferentes é permitido
- [ ] Teste automatizado confirma que tentar acessar customer/produto de
outro tenant retorna 404
- [ ] Todos os endpoints desta etapa são inacessíveis com token master
"puro" sem contexto de tenant (ou documentar explicitamente se o
master deve conseguir acessar em modo de suporte — decisão a
confirmar antes de implementar)