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:
2026-08-16 09:41:13 -03:00
co-authored by Claude Sonnet 5
parent f9738e54da
commit 323912748f
179 changed files with 29312 additions and 22 deletions
+261
View File
@@ -0,0 +1,261 @@
# SeConectai Vendas — Schema de Frontend (Web Responsivo)
Este documento define a arquitetura do frontend que vai consumir a API
já especificada nas etapas 1–8. Cobre estrutura de telas, navegação,
sistema de design e a estratégia de responsividade para funcionar bem
tanto em tela de PC quanto em smartphone.
## 1. Visão geral
Uma única aplicação, com duas áreas autenticadas separadas:
- **Área master** (`/master/...`) — seu painel, gestão dos tenants.
- **Área tenant** (`/app/...`) — painel que seus clientes usam no dia a
dia (vendas, clientes, produtos, alertas).
Ambas consomem a mesma API REST do backend. O layout de cada área é
diferente (menu, cores, permissões), mas compartilham o mesmo sistema de
design (componentes, tokens, grid responsivo).
## 2. Stack sugerida
- **Next.js 14+ (App Router)** + React 18 + TypeScript
- **Tailwind CSS** para estilos utilitários, com tokens de design via
CSS variables (necessário para o whitelabel: cor primária muda por
tenant em tempo de execução, não pode ser fixa no build)
- **shadcn/ui** como base de componentes acessíveis, customizados por
cima (não usar como está "fora da caixa" — ajustar aos tokens do
projeto)
- **TanStack Query (React Query)** para cache/estado de dados vindos da
API (listagens, dashboards)
- **React Hook Form + Zod** para formulários e validação — os schemas
Zod devem espelhar os DTOs do backend
- **Recharts** para os gráficos de dashboard (resumo de vendas etc)
- Estado de UI leve (sidebar aberta/fechada, tema) via Context/Zustand —
não precisa de Redux para este escopo
## 3. Estratégia de responsividade
Mobile-first. Breakpoints (padrão Tailwind, manter):
| Breakpoint | Largura | Uso principal |
|------------|-----------|----------------|
| base | < 640px | smartphone |
| `sm` | ≥ 640px | smartphone grande / phablet |
| `md` | ≥ 768px | tablet |
| `lg` | ≥ 1024px | desktop |
| `xl` | ≥ 1280px | desktop grande |
Regras de layout por faixa:
- **Desktop (`lg` e acima):** sidebar fixa lateral (~240px) + topbar.
Conteúdo em grid de 2 colunas quando fizer sentido (ex: formulário +
resumo lateral).
- **Tablet (`md`):** sidebar colapsada só com ícones (expande em hover
ou toque), conteúdo em coluna única ou 2 colunas conforme espaço.
- **Mobile (abaixo de `md`):**
- Sidebar vira **drawer** (menu lateral que desliza, acionado por
ícone de hambúrguer na topbar).
- **Bottom tab bar fixa** com os 4–5 itens mais usados de cada área
(ex. no tenant: Dashboard, Clientes, Vendas, Recebimentos, Mais).
- Tabelas **não** fazem scroll horizontal como solução padrão — cada
linha vira um **card empilhado** (rótulo: valor), com as
informações mais importantes em destaque e as secundárias
colapsadas/expansíveis.
- Formulários em coluna única; campos grandes o suficiente para touch
(mínimo 44x44px de área de toque).
- Modais viram **tela cheia** ou **bottom sheet** (desliza de baixo),
nunca uma caixa pequena centralizada como no desktop.
- Filtros de listagem (que no desktop ficam visíveis lateralmente)
viram um botão "Filtros" que abre um bottom sheet no mobile.
Checklist de teste obrigatório em **toda** tela construída: 375px
(mobile pequeno), 768px (tablet) e 1280px (desktop), sem scroll
horizontal indevido em nenhuma delas.
## 4. Mapa de rotas
### Público (sem autenticação)
```
/login → detecta master ou tenant pelo e-mail/domínio
/esqueci-senha
/redefinir-senha/:token
```
### Área master — `/master`
```
/master/dashboard
/master/tenants (lista)
/master/tenants/novo
/master/tenants/:id (detalhe, edição, faturas do tenant)
/master/planos
/master/faturas (visão consolidada de todas as mensalidades)
/master/evolution-config
/master/alertas/templates
/master/alertas/logs
/master/configuracoes (perfil do admin master, senha, MFA)
```
### Área tenant — `/app`
```
/app/dashboard
/app/clientes (lista)
/app/clientes/novo
/app/clientes/:id (detalhe, contatos, histórico de vendas)
/app/produtos (produtos e serviços)
/app/produtos/novo
/app/produtos/:id
/app/vendas (lista)
/app/vendas/nova
/app/vendas/:id (detalhe, itens, parcelas)
/app/recebimentos (contas a receber, marcar pago)
/app/whatsapp (instâncias Evolution, QR code, status)
/app/email-config
/app/alertas/templates
/app/alertas/logs
/app/equipe (usuários do tenant, só para tenant_admin)
/app/perfil (logo, cor, dados da empresa)
```
## 5. Navegação e layout por área
**Desktop:**
- Sidebar: logo do tenant (ou logo master) no topo, itens de menu com
ícone + label, indicador do item ativo, avatar do usuário + logout no
rodapé.
- Topbar: breadcrumb da página atual, sino de notificações (alertas
recentes), busca rápida (clientes/vendas).
**Mobile:**
- Topbar fixa: logo compacta (só o símbolo, não o nome completo) +
ícone de menu (drawer) + sino de notificações.
- Drawer: réplica do menu completo da sidebar desktop, ocupa a tela
inteira ou 80% da largura.
- Bottom tab bar: 4 itens fixos mais "Mais" (que abre o restante do
menu). Ícone + label curto embaixo.
## 6. Sistema de design (tokens)
Paleta **neutra da plataforma** (usada em textos, fundos, bordas —
igual em master e em todos os tenants):
- `--neutral-950: #12141A` — texto principal
- `--neutral-500: #6B7280` — texto secundário
- `--neutral-200: #E5E7EB` — bordas
- `--neutral-50: #F8F9FB` — fundo de página
- `--surface: #FFFFFF` — fundo de cards/painéis
- `--danger: #DC2626` — erros, valores atrasados
- `--success: #16A34A` — pagos, confirmados
- `--warning: #D97706` — pendências, avisos
Cor de marca **do painel master** (fixa, identidade do SeConectai
Vendas): `--brand-master: #1E3A5F` (azul petróleo escuro) com acento
`--brand-master-accent: #2DD4BF` (verde-água) — usada apenas na área
`/master`.
Cor de marca **de cada tenant** (dinâmica, whitelabel): variável
`--color-primary`, resolvida em runtime a partir de
`tenants.cor_primaria` (endpoint público de tema, já definido na Etapa
8 do backend) e aplicada via CSS variable no layout de `/app`. Se o
tenant não definiu cor própria, cair para um azul neutro padrão
(`#2563EB`). Validar contraste mínimo (WCAG AA) contra branco antes de
aplicar — se a cor escolhida pelo tenant não passar, usar uma versão
escurecida automaticamente para texto sobre fundo colorido.
Tipografia: uma família para UI (ex: Inter ou similar, boa legibilidade
em telas pequenas e números tabulares para valores monetários) e uso de
`font-variant-numeric: tabular-nums` em qualquer coluna de valores para
alinhamento visual em tabelas/cards.
## 7. Componentes de design system (biblioteca a construir)
Base (`components/ui/`): Button, Input, Select, DatePicker, Textarea,
Table (com variante que vira lista de Cards abaixo do breakpoint `md`),
Modal/Sheet (adaptável tela-cheia no mobile), Toast, Badge/StatusPill
(para status de fatura/parcela/venda), Card, Pagination, EmptyState,
Skeleton (loading), Tabs, FormField (wrapper de label+erro+input).
Layout (`components/layout/`): Sidebar, Topbar, Drawer, BottomTabBar,
Breadcrumb.
Domínio (`components/domain/`): ClienteCard, VendaForm, ParcelaRow,
ProdutoForm, StatusFaturaBadge, ResumoVendasChart, InstanciaWhatsappCard.
## 8. Dados e autenticação no client
- **TanStack Query** para toda chamada de leitura (listagens,
dashboards, detalhes), com invalidação automática após mutations
(criar/editar/excluir).
- **Zod schemas** espelhando os DTOs do backend — usados tanto na
validação de formulário quanto na tipagem das respostas da API (fonte
única de verdade dos tipos no frontend).
- **Access token em memória** (não em `localStorage`, para reduzir
superfície de XSS); **refresh token em cookie `httpOnly`**, setado
pelo backend. Interceptor de requisição renova o access token
automaticamente em caso de 401 e repete a chamada original.
- **Middleware do Next.js** protegendo `/master/*` e `/app/*`,
verificando sessão válida antes de renderizar a página (evita "flash"
de conteúdo protegido).
- Tema (cor primária + logo) resolvido no login: chama o endpoint
público de tema com o identificador do tenant, aplica as CSS
variables antes mesmo do usuário autenticar (tela de login já com a
cara do tenant certo).
## 9. Estrutura de pastas sugerida
```
frontend/
├── app/
│ ├── (public)/
│ │ ├── login/
│ │ ├── esqueci-senha/
│ │ └── redefinir-senha/[token]/
│ ├── master/
│ │ ├── layout.tsx
│ │ ├── dashboard/
│ │ ├── tenants/
│ │ ├── planos/
│ │ ├── faturas/
│ │ ├── evolution-config/
│ │ └── alertas/
│ └── app/
│ ├── layout.tsx
│ ├── dashboard/
│ ├── clientes/
│ ├── produtos/
│ ├── vendas/
│ ├── recebimentos/
│ ├── whatsapp/
│ ├── email-config/
│ ├── alertas/
│ ├── equipe/
│ └── perfil/
├── components/
│ ├── ui/
│ ├── layout/
│ └── domain/
├── lib/
│ ├── api/ (client HTTP + funções por domínio)
│ ├── auth/
│ ├── theme/
│ └── validators/ (schemas Zod)
├── hooks/
└── styles/
└── tokens.css (CSS variables da paleta e tipografia)
```
## 10. Checklist de responsividade (aplicar em toda tela nova)
- [ ] Testado em 375px, 768px e 1280px sem overflow horizontal indevido
- [ ] Tabelas de listagem viram cards empilhados abaixo de `md`
- [ ] Navegação principal acessível via bottom tab bar ou drawer no mobile
- [ ] Touch targets ≥ 44x44px em elementos interativos no mobile
- [ ] Formulário utilizável com teclado virtual aberto (campo em foco
não fica escondido atrás do teclado)
- [ ] Modais/diálogos viram tela cheia ou bottom sheet no mobile
- [ ] Cor primária dinâmica do tenant aplicada corretamente em
botões/links/destaques, com contraste validado
- [ ] Foco de teclado visível em todos os elementos interativos
(acessibilidade, não só mobile)
- [ ] Estados de carregamento (skeleton) e vazio (empty state) tratados
em toda listagem