Initial project import

This commit is contained in:
Tiago
2026-09-29 12:12:31 -03:00
commit c435bb5e23
120 changed files with 5371 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
# Prompt 05 — Painel Master: clientes, planos e funcionalidades
## Contexto
Prompts 01–04 concluídos: schema completo (master + tenant), provisionamento de tenant, autenticação (master/funcionário/API Key) funcionando. **Leia `10-tracker-progresso.md` antes de começar.**
Este prompt implementa os endpoints do menu **Master → Clientes** e **Master → Planos**, incluindo o provisionamento de empresa nova (usa o `TenantProvisioner` do Prompt 03) e o toggle de funcionalidades por empresa.
## Objetivo
CRUD de empresas (clientes), CRUD de planos, ativação/desativação de funcionalidades por empresa, listagem de logs de envio com erro e listagem de clientes pagantes/inadimplentes.
Todos os endpoints deste prompt exigem `exigirMaster` (Prompt 04).
## Especificação
### 1. Clientes (empresas)
```
POST /api/master/empresas
body: {"nome": "...", "cnpj": "...", "slug": "..."}
→ valida slug único, cria registro em `empresas` (status inicial: 'provisionando'),
chama TenantProvisioner de forma síncrona (aceitável nesta fase — trocar por fila
assíncrona é uma melhoria futura, não bloquear o prompt por isso),
atualiza status para 'ativa' ao concluir (ou 'provisionamento_pendente' se falhar)
→ retorna o registro criado, incluindo se o provisionamento deu certo
GET /api/master/empresas
query params opcionais: ?status=ativa|bloqueada|cancelada
→ lista com nome, status, plano vinculado (join com assinaturas+planos), situação do
período de uso vigente (pago/pendente/bloqueado)
GET /api/master/empresas/{id}
PUT /api/master/empresas/{id} (editar nome/cnpj — NÃO permite editar slug/database_name)
```
### 2. Funcionários da empresa (cadastro pelo master também, já que "cadastro da empresa é feito pelo master")
```
POST /api/master/empresas/{id}/funcionarios
body: {"nome", "email", "senha" (texto puro, só nesta chamada — vira hash), "cargo"}
GET /api/master/empresas/{id}/funcionarios
```
*(Nota: o próprio escritório pode ter uma tela de gestão de funcionários mais pra frente, mas o cadastro inicial do primeiro funcionário é feito pelo master junto com a empresa, senão ninguém consegue logar.)*
### 3. Funcionalidades
```
GET /api/master/empresas/{id}/funcionalidades
→ lista todas as `funcionalidades` com um booleano indicando se está ativa pra essa empresa
POST /api/master/empresas/{id}/funcionalidades/{chave}/ativar
POST /api/master/empresas/{id}/funcionalidades/{chave}/desativar
→ grava em empresa_funcionalidades (liberado_em=now(), liberado_por=<funcionario_id do
token master, se aplicável, senão null>)
```
Ao criar uma empresa vinculada a um plano (Prompt seguinte trata a criação da assinatura), as funcionalidades de `plano_funcionalidades` daquele plano devem ser copiadas automaticamente como "ativas" em `empresa_funcionalidades` — implementar esse copy aqui mesmo, no momento da criação da empresa, SE o body de criação já incluir um `plano_id` opcional.
### 4. Planos
```
GET /api/master/planos
POST /api/master/planos body: {"nome", "valor_mensal_centavos", "descricao", "funcionalidades": ["chave1","chave2"]}
PUT /api/master/planos/{id}
```
Ao criar/editar um plano com a lista de `funcionalidades`, sincronizar `plano_funcionalidades` (remover as que saíram, inserir as novas).
### 5. Logs de envio e clientes pagantes
```
GET /api/master/logs-envio?status=falhou&empresa_id=X (empresa_id opcional)
→ lista de logs_envio_avisos, mais recentes primeiro, paginado (limit/offset)
GET /api/master/empresas?situacao=pagante
→ reaproveita o GET /api/master/empresas, com filtro adicional: join em periodos_uso
do mês corrente, status='pago'
POST /api/master/empresas/{id}/lembrete-cobranca
body: {"canal": "whatsapp"|"email"}
→ grava em lembretes_cobranca; o ENVIO de fato (mensagem real) só é implementado no
Prompt 08, quando a integração Evolution/e-mail existir — por enquanto, só registra
a intenção e retorna sucesso (deixar um TODO claro no código apontando pro Prompt 08)
```
## Critérios de aceite
- [ ] Criar uma empresa via `POST /api/master/empresas` de fato cria o database `db_empresa_<slug>` (reaproveitando o Prompt 03) e um primeiro funcionário consegue logar em seguida via `POST /api/auth/login`.
- [ ] Criar empresa com slug já existente retorna erro 409, sem tentar criar database duplicado.
- [ ] Ativar/desativar funcionalidade reflete corretamente em `GET /api/master/empresas/{id}/funcionalidades`.
- [ ] Criar um plano com 3 funcionalidades e depois criar uma empresa apontando pra esse plano faz as 3 aparecerem já ativas em `empresa_funcionalidades`.
- [ ] `GET /api/master/logs-envio?status=falhou` funciona mesmo sem nenhum log ainda (retorna lista vazia, não erro).
- [ ] Todos os endpoints deste prompt retornam 401 se chamados sem token master válido.
## Ao concluir
Atualizar `10-tracker-progresso.md`: Prompt 05 concluído, data, resumo. Confirmar Prompts 01–04 seguem marcados.