70 lines
3.3 KiB
Markdown
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)
|