Frontend completo (Etapas 11-18) e extensões de backend (Etapas 13 e 18)
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>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user