# 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=) ``` 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_` (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.