Módulo 15: Portal do Cliente — API
Status: Rascunho Inicial Regras de negócio: ver
regras-negocio/15_portal_cliente.mdDomínio: verdominio/cliente.md
1. Contratos de API (Públicas e Protegidas por JWT)
A API do portal roda sob o prefixo /api/client-portal/ e é protegida por um middleware específico que valida tokens JWT emitidos unicamente para clientes finais (não operacionais).
1.1 Autenticação e Recuperação
POST /api/client-portal/auth/login
Auth: Pública
Body: { cpf_cnpj: string, senha: string }
Return: 200 OK
{
"token_jwt": "string",
"cliente": { "id": "uuid", "nome": "string", "email": "string" },
"tenant_config": {
"nome_fantasia": "string",
"logo_url": "string",
"cor_primaria": "string",
"cor_secundaria": "string",
"radius": "string",
"fone_assistencia_24h": "string"
}
}
Errors:
401 — Credenciais inválidas ou CPF/CNPJ não cadastrado.
POST /api/client-portal/auth/solicitar-otp
Auth: Pública
Body: { cpf_cnpj: string }
Return: 200 OK (Manda código OTP de 6 dígitos via WhatsApp cadastrado).
POST /api/client-portal/auth/validar-otp
Auth: Pública
Body: { cpf_cnpj: string, codigo_otp: string }
Return: 200 OK { token_redefinicao_jwt: "string" }
1.2 Área Logada do Portal do Cliente
GET /api/client-portal/meus-contratos
Auth: Token JWT Cliente
Return: [
{
"plano_contratado_id": "uuid",
"veiculo": { "placa": "string", "marca": "string", "modelo": "string", "ano_fabricacao": integer },
"plano_nome": "string",
"status": "ATIVO | INADIMPLENTE | SUSPENSO",
"coberturas": ["string"],
"vigencia_inicio": "datetime",
"vigencia_fim": "datetime"
}
]
GET /api/client-portal/financeiro/faturas
Auth: Token JWT Cliente
Return: [
{
"fatura_id": "string",
"competencia": "YYYY-MM",
"vencimento": "date",
"valor": "decimal",
"status": "PAGO | ABERTO | ATRASADO",
"linha_digitavel": "string | null",
"pix_copia_cola": "string | null",
"url_pdf": "string | null"
}
]
Nota: O CRM Server age como proxy para obter estes dados da API do ERP. Se o ERP falhar, o CRM retorna status HTTP 200 contendo uma lista vazia e uma flag de indisponibilidade (`erp_online: false`).
POST /api/client-portal/servicos/abrir-sinistro
Auth: Token JWT Cliente
Body:
{
"veiculo_id": "uuid",
"tipo_evento": "COLISAO | ROUBO_FURTO | INCENDIO | DANOS_NATUREZA",
"descricao": "string",
"data_hora_evento": "datetime",
"endereco_evento": "string",
"boletim_ocorrencia_base64": "string (PDF/Imagem)",
"boletim_ocorrencia_nome": "string",
"fotos_evidencia": ["string (Base64)"]
}
Return: 201 Created { protocolo: "string", ticket_id: "uuid" }
PATCH /api/client-portal/perfil/atualizar-cadastro
Auth: Token JWT Cliente
Body: { telefone: "string", email: "string", endereco: {...} }
Return: 200 OK
2. Metadados Adicionados à Tabela Cliente (Módulo 06)
{
"senha_hash": "string | null",
"ultimo_login_app": "datetime | null",
"token_recuperacao": "string | null",
"token_expira_em": "datetime | null",
"aceitou_termos_app": "boolean"
}
3. Segurança e Boas Práticas
| Regra | Implementação |
|---|---|
| JWT Restrito (RLS) | O token JWT do portal do cliente deve conter escopo diferenciado (ex: role: client_portal) impedindo que seja aceito em endpoints do painel operacional do CRM. Toda query deve filtrar pelo cliente_id extraído do payload do JWT. |
| Rate Limiting de OTP | O endpoint de solicitação de OTP deve ser limitado a 1 envio a cada 60 segundos por IP e CPF. Limitar tentativas de validação a no máximo 5 erros por minuto para evitar brute force. |
| Higienização de Uploads | Imagens e PDFs enviados no aviso de sinistro devem ter suas extensões e assinaturas binárias (Magic Numbers) inspecionadas no backend antes de serem salvas. Limite máximo de arquivo: 10MB. |
| Isolamento de Banco | Consultas das APIs do Portal do Cliente não devem fazer queries complexas contendo joins ou subconsultas que envolvam tabelas corporativas (como comissões, equipes ou logs de auditoria interna). |