Adiciona o frontend Next.js em frontend/ (setup, design system, autenticação/tema, layout/navegação, área master, área tenant completa: clientes, produtos, vendas, recebimentos, whatsapp, e-mail, alertas, equipe e perfil). Estende o backend de forma aditiva e autorizada: cookie httpOnly para refresh token (Etapa 13) e CRUD de equipe + edição de perfil do tenant (Etapa 18, módulo src/modules/equipe/ novo e PUT /tenant/perfil). Detalhes completos em Etapas/V2/*. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
103 lines
5.3 KiB
Markdown
103 lines
5.3 KiB
Markdown
# Etapa 13 — Autenticação e Tema Dinâmico (Whitelabel)
|
|
|
|
## Contexto do projeto
|
|
|
|
Continuação do frontend do **SeConectai Vendas**. Já existem: projeto
|
|
configurado (Etapa 11) e a biblioteca de componentes base (Etapa 12). O
|
|
backend já expõe toda a API de autenticação (login master/tenant,
|
|
refresh, esqueci senha) e o endpoint público de tema por tenant
|
|
(definidos nas Etapas 2 e 8 do backend).
|
|
|
|
## Objetivo desta etapa
|
|
|
|
Implementar as telas públicas de autenticação, o mecanismo de sessão no
|
|
client (armazenamento de token, renovação automática, proteção de
|
|
rotas), e a resolução do tema (logo + cor) por tenant antes mesmo do
|
|
login.
|
|
|
|
## Tarefas
|
|
|
|
1. **Telas públicas (`app/(public)/`)**
|
|
- **`/login`**: formulário de e-mail + senha. Deve detectar se o
|
|
login é de master ou de tenant (definir estratégia: campo
|
|
oculto/toggle, ou dois formulários, ou detecção automática pelo
|
|
backend a partir do e-mail — escolher a mais simples de implementar
|
|
e documentar a decisão). Erros de credencial inválida devem ser
|
|
claros mas não revelar se o e-mail existe ou não (mensagem genérica
|
|
"e-mail ou senha inválidos").
|
|
- **`/esqueci-senha`**: formulário de e-mail, chama o endpoint de
|
|
recuperação, sempre mostra mensagem de sucesso genérica (não
|
|
revelar se o e-mail existe no sistema).
|
|
- **`/redefinir-senha/[token]`**: formulário de nova senha (com
|
|
confirmação), valida força mínima no client espelhando a regra do
|
|
backend, trata token expirado/inválido com mensagem clara.
|
|
- Todas essas telas devem ser **totalmente responsivas**: em mobile,
|
|
formulário ocupa a largura da tela com padding adequado; em
|
|
desktop, formulário centralizado com largura máxima (ex: 420px) e
|
|
fundo com identidade visual do tema resolvido (ver item 3).
|
|
|
|
2. **Gerenciamento de sessão (`lib/auth/`)**
|
|
- Access token guardado **em memória** (ex: em um Context/store, não
|
|
em `localStorage`/`sessionStorage`).
|
|
- Refresh token: o backend deve setar como cookie `httpOnly`; o
|
|
client não manipula esse cookie diretamente, apenas confia que ele
|
|
é enviado automaticamente nas chamadas relevantes.
|
|
- Interceptor no `lib/api/client.ts` (gancho deixado pronto na Etapa
|
|
11): ao receber 401, tenta chamar o endpoint de refresh
|
|
automaticamente; se conseguir, repete a requisição original com o
|
|
novo token; se falhar, desloga e redireciona para `/login`.
|
|
- Função `logout()` que limpa o estado em memória e chama o endpoint
|
|
de logout do backend (revoga o refresh token no servidor).
|
|
|
|
3. **Middleware de proteção de rotas**
|
|
- Middleware do Next.js protegendo `/master/*` e `/app/*`: verifica
|
|
se existe sessão válida (ex: checando um cookie de sinalização não
|
|
sensível, já que o access token real fica só em memória no client —
|
|
definir estratégia de verificação no servidor sem expor o token) e
|
|
redireciona para `/login` se não houver.
|
|
- Usuário master tentando acessar `/app/*` (ou vice-versa) deve ser
|
|
redirecionado para a área correta, não para login.
|
|
- Após login bem-sucedido, redirecionar automaticamente para
|
|
`/master/dashboard` ou `/app/dashboard` conforme o tipo de usuário
|
|
retornado pela API.
|
|
|
|
4. **Tema dinâmico por tenant (`lib/theme/`)**
|
|
- Na tela `/login`, antes de qualquer autenticação, resolver o tema:
|
|
se a URL/subdomínio/parâmetro identificar um tenant específico,
|
|
chamar o endpoint público `/public/tenants/:slugOuId/tema` e
|
|
aplicar `--color-primary` e o logo retornados. Se não houver tenant
|
|
identificável (ex: acesso genérico), mostrar o tema padrão da
|
|
plataforma.
|
|
- Após o login, na área `/app`, resolver o tema a partir do perfil do
|
|
tenant autenticado (não precisa mais do endpoint público).
|
|
- Implementar a validação de contraste descrita na seção 6 do schema:
|
|
se `cor_primaria` do tenant não atingir contraste mínimo (WCAG AA)
|
|
contra branco, escurecer automaticamente antes de aplicar como cor
|
|
de texto/ícone sobre fundo colorido (manter a cor original para
|
|
fundos, ajustar só onde teria problema de legibilidade).
|
|
|
|
5. **Feedback de erro e loading**
|
|
- Todos os formulários desta etapa usam os componentes `FormField`,
|
|
`Button` (estado `loading`) e `Toast` já construídos na Etapa 12 —
|
|
nenhuma solução de UI paralela aqui.
|
|
|
|
## Critérios de aceite
|
|
|
|
- [ ] Login master e login tenant funcionam ponta a ponta com o backend
|
|
real
|
|
- [ ] Sessão expira corretamente e é renovada automaticamente via
|
|
refresh (testar deixando o access token expirar e fazendo uma
|
|
ação)
|
|
- [ ] Logout limpa a sessão e o backend revoga o refresh token
|
|
- [ ] Middleware bloqueia acesso não autenticado a `/master/*` e
|
|
`/app/*`, redirecionando para `/login`
|
|
- [ ] Usuário master não consegue acessar `/app/*` diretamente pela URL
|
|
(e vice-versa) sem ser redirecionado
|
|
- [ ] Fluxo completo de esqueci/redefinir senha funciona, incluindo
|
|
tratamento de token expirado
|
|
- [ ] Tela de login aplica a cor/logo do tenant certo quando o tenant é
|
|
identificável, e cai no tema padrão quando não é
|
|
- [ ] Cor de tenant com baixo contraste é ajustada automaticamente onde
|
|
necessário, sem quebrar a legibilidade
|
|
- [ ] Todas as telas desta etapa testadas em 375px, 768px e 1280px
|