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:
@@ -181,6 +181,26 @@ propositalmente para depois — detalhar em Observações).
|
||||
`npm run lint`, `tsc --noEmit` e `npm run build` (produção) também
|
||||
passam sem erros; smoke test manual via `curl` contra a imagem
|
||||
`production` real confirmou login + guards funcionando fim a fim.
|
||||
- **[2026-08-15, revisitado pela Etapa 13 do frontend]** Adicionado
|
||||
suporte a cookie httpOnly para o refresh token (`security.util.ts`,
|
||||
`auth.controller.ts`, `RefreshDto`/`LogoutDto`) — mudança aditiva, os
|
||||
21 testes originais continuam passando sem alteração, mais 4 novos
|
||||
cobrindo o cookie (total 24/24 em `auth.e2e-spec.ts`). Detalhe completo
|
||||
em `Etapas/V2/20-controle-de-progresso-frontend.md`, Etapa 13.
|
||||
- **[2026-08-16, revisitado pela Etapa 18 do frontend]** `tenant_users`
|
||||
(criada nesta etapa) ganhou CRUD real do lado do tenant: novo módulo
|
||||
`src/modules/equipe/` (`GET/POST /tenant/equipe`, `PATCH
|
||||
/tenant/equipe/:id`, só `tenant_admin`, RLS via `TenantContextService`
|
||||
como `customers`/`products` da Etapa 5) — o `GET /auth/tenant/users`
|
||||
deste módulo continua exatamente como estava, só leitura/demonstração,
|
||||
não foi tocado. Também aditivo: `PUT /tenant/perfil`
|
||||
(`nome_fantasia`/`razao_social`) em `src/modules/tenant-profile/`, ao
|
||||
lado do `PUT /tenant/perfil/cor` já existente da Etapa 8. Mudança
|
||||
autorizada explicitamente pelo usuário antes de implementar (a Etapa 18
|
||||
do frontend precisava de CRUD real de equipe e edição de perfil, que
|
||||
não existiam). Detalhe completo — DTOs, regras de limite de plano,
|
||||
auto-bloqueio, testes e2e — em
|
||||
`Etapas/V2/20-controle-de-progresso-frontend.md`, Etapa 18.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# SeConectai Vendas — Prompts de Build Faseado
|
||||
|
||||
Este pacote contém 8 prompts sequenciais e autocontidos para entregar a uma
|
||||
IA de geração de código (Claude Code, Cursor, Windsurf etc). Cada arquivo
|
||||
pode ser colado como um prompt único — eles já trazem o contexto necessário
|
||||
para não depender de memória de conversa anterior.
|
||||
|
||||
## Ordem obrigatória — Backend
|
||||
|
||||
1. `01-setup-projeto.md` — estrutura base, Docker Compose, Postgres, Prisma
|
||||
2. `02-autenticacao-rls.md` — login master/tenant, JWT, RLS
|
||||
3. `03-painel-master-tenants.md` — CRUD de tenants, planos, faturas
|
||||
4. `04-integracoes-evolution-email.md` — Evolution API, instâncias WhatsApp, SMTP
|
||||
5. `05-painel-tenant-customers-produtos.md` — CRUD de clientes e produtos/serviços
|
||||
6. `06-vendas-dashboards.md` — vendas, parcelas, resumos
|
||||
7. `07-motor-de-alertas.md` — BullMQ, templates, disparo e logs
|
||||
8. `08-personalizacao-whitelabel.md` — logo/cor por tenant, ajustes finais
|
||||
|
||||
Controle de progresso: `09-controle-de-progresso.md`
|
||||
|
||||
## Ordem obrigatória — Frontend
|
||||
|
||||
Pré-requisito: backend concluído (ou ao menos as etapas cujos endpoints
|
||||
cada tela consome). Arquitetura de referência:
|
||||
`10-frontend-schema-arquitetura.md`.
|
||||
|
||||
11. `11-frontend-setup-projeto.md` — Next.js, Tailwind, tokens, estrutura
|
||||
12. `12-frontend-design-system.md` — biblioteca de componentes base
|
||||
13. `13-frontend-autenticacao-tema.md` — login, sessão, tema dinâmico whitelabel
|
||||
14. `14-frontend-layout-navegacao.md` — sidebar/topbar/drawer/bottom-nav
|
||||
15. `15-frontend-area-master.md` — telas de negócio do painel master
|
||||
16. `16-frontend-area-tenant-cadastros.md` — dashboard, clientes, produtos
|
||||
17. `17-frontend-area-tenant-vendas.md` — vendas, parcelas, financeiro
|
||||
18. `18-frontend-area-tenant-integracoes-perfil.md` — WhatsApp, e-mail, alertas, equipe, whitelabel
|
||||
19. `19-frontend-polimento-testes.md` — responsividade, acessibilidade, E2E
|
||||
|
||||
Controle de progresso: `20-controle-de-progresso-frontend.md`
|
||||
|
||||
## Arquivos de controle de progresso (obrigatórios)
|
||||
|
||||
`09-controle-de-progresso.md` (backend) e
|
||||
`20-controle-de-progresso-frontend.md` (frontend) são o estado oficial
|
||||
de cada parte do projeto. Regras:
|
||||
|
||||
- **Sempre envie o arquivo correspondente junto com o prompt de cada
|
||||
etapa** (o de backend para as etapas 1–8, o de frontend para as
|
||||
etapas 11–19).
|
||||
- A IA deve lê-lo antes de começar e recusar iniciar uma etapa se a
|
||||
anterior não estiver 100% concluída na checklist.
|
||||
- Ao final de cada etapa, a IA deve devolver o arquivo atualizado (itens
|
||||
marcados, status geral e observações preenchidas) — é esse arquivo
|
||||
atualizado que você guarda e reenvia na próxima etapa/sessão.
|
||||
- Sem esse arquivo, uma IA nova (em outra sessão) não tem como saber o
|
||||
que já foi feito — por isso ele substitui a necessidade de repetir todo
|
||||
o histórico da conversa.
|
||||
|
||||
## Como usar cada prompt
|
||||
|
||||
- Rode nessa ordem — cada etapa assume que a anterior está pronta e
|
||||
funcionando (migrations aplicadas, testes passando).
|
||||
- Ao final de cada etapa, confira o checklist de "Critérios de aceite"
|
||||
antes de avançar para a próxima. Se algo não for atendido, peça correção
|
||||
antes de seguir.
|
||||
- O arquivo `seconectai-vendas-schema.sql` é a fonte de verdade do modelo
|
||||
de dados — qualquer etapa que crie migration deve refletir exatamente
|
||||
essas tabelas (a IA pode adaptar para sintaxe Prisma, mas a estrutura,
|
||||
nomes de campo e tipos devem ser preservados).
|
||||
- Cada prompt já repete o essencial do contexto (stack, convenções), então
|
||||
eles funcionam mesmo em uma conversa nova/sessão nova com a IA.
|
||||
|
||||
## Stack fixada em todas as etapas
|
||||
|
||||
- Node.js 20+ / TypeScript
|
||||
- NestJS (modular por domínio)
|
||||
- PostgreSQL 16 + Prisma ORM
|
||||
- Redis + BullMQ (a partir da etapa 7)
|
||||
- Docker + Docker Compose
|
||||
- Autenticação: JWT (access curto) + refresh token com rotação, senha com
|
||||
argon2id
|
||||
- Multi-tenancy: banco único, isolamento por `tenant_id` + Row Level
|
||||
Security do Postgres
|
||||
@@ -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
|
||||
@@ -0,0 +1,92 @@
|
||||
# Etapa 11 — Setup do Projeto Frontend
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Estou construindo o frontend do **SeConectai Vendas** — CRM/vendas
|
||||
multi-tenant. O backend (API REST em NestJS) já está pronto, seguindo o
|
||||
schema e as etapas descritas em documentos separados. O frontend consome
|
||||
essa API e tem duas áreas: painel **master** (`/master`) e painel
|
||||
**tenant** (`/app`).
|
||||
|
||||
A arquitetura completa (rotas, breakpoints, tokens de design, estrutura
|
||||
de pastas) está definida no arquivo `10-frontend-schema-arquitetura.md`
|
||||
— **use esse arquivo como fonte de verdade** para tudo que for construído
|
||||
nesta e nas próximas etapas.
|
||||
|
||||
Esta é a **Etapa 1 de 9 do frontend** (numerada como Etapa 11 no conjunto
|
||||
geral do projeto, para não colidir com as 8 etapas do backend). Aqui é
|
||||
só a fundação — nenhuma tela de negócio ainda.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Inicializar o projeto Next.js com toda a configuração base: Tailwind com
|
||||
os tokens de design do schema, estrutura de pastas, variáveis de
|
||||
ambiente, lint/format, e uma página inicial validando a conexão com a
|
||||
API do backend.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **Inicialização do projeto**
|
||||
- Next.js 14+ com App Router, TypeScript, ESLint já integrado.
|
||||
- Configurar Tailwind CSS.
|
||||
- Configurar Prettier + regra de integração com ESLint (sem conflito
|
||||
de formatação).
|
||||
|
||||
2. **Tokens de design**
|
||||
- Criar `styles/tokens.css` com todas as CSS variables definidas na
|
||||
seção 6 do schema (`--neutral-*`, `--surface`, `--danger`,
|
||||
`--success`, `--warning`, `--brand-master`, `--brand-master-accent`,
|
||||
`--color-primary` com fallback `#2563EB`).
|
||||
- Configurar `tailwind.config.ts` para expor essas variáveis como
|
||||
cores utilitárias (ex: `bg-primary`, `text-danger`), em vez de usar
|
||||
`var(--...)` espalhado pelo código.
|
||||
- Configurar fonte (Inter ou equivalente definida no schema), incluindo
|
||||
`font-variant-numeric: tabular-nums` disponível como classe utilitária
|
||||
para colunas de valores monetários.
|
||||
|
||||
3. **Estrutura de pastas**
|
||||
- Criar exatamente a estrutura de pastas da seção 9 do schema:
|
||||
`app/(public)/`, `app/master/`, `app/app/`, `components/ui/`,
|
||||
`components/layout/`, `components/domain/`, `lib/api/`,
|
||||
`lib/auth/`, `lib/theme/`, `lib/validators/`, `hooks/`, `styles/`.
|
||||
- Cada pasta de rota deve existir com um `page.tsx` placeholder (ex:
|
||||
"Em construção — Etapa X") para validar que o roteamento do mapa de
|
||||
rotas inteiro já resolve sem erro 404, mesmo antes das telas reais
|
||||
existirem.
|
||||
|
||||
4. **Variáveis de ambiente e cliente HTTP base**
|
||||
- `.env.local.example` com `NEXT_PUBLIC_API_URL` e demais chaves que
|
||||
forem necessárias.
|
||||
- Criar `lib/api/client.ts`: wrapper mínimo sobre `fetch` (ou axios,
|
||||
justificar a escolha) com base URL configurável, tratamento de erro
|
||||
padronizado (parse de erro da API em formato consistente), e um
|
||||
ponto único de onde o interceptor de refresh token será plugado na
|
||||
Etapa 13 (deixar o gancho pronto, sem implementar auth ainda).
|
||||
|
||||
5. **Página de diagnóstico**
|
||||
- Uma rota simples (ex: `/diagnostico`, pode ser removida depois) que
|
||||
chama `GET /health` do backend e mostra o resultado — só para
|
||||
confirmar que a integração frontend↔backend está funcionando de
|
||||
ponta a ponta antes de seguir.
|
||||
|
||||
6. **Qualidade**
|
||||
- Scripts no `package.json`: `dev`, `build`, `start`, `lint`,
|
||||
`format`.
|
||||
- Configurar Husky + lint-staged (ou equivalente) para rodar lint no
|
||||
pre-commit, se fizer sentido para o fluxo do projeto.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] `npm run dev` sobe o projeto sem erro
|
||||
- [ ] Todas as rotas do mapa de rotas (seção 4 do schema) resolvem, com
|
||||
página placeholder, sem 404
|
||||
- [ ] `tokens.css` contém todas as variáveis do schema, aplicadas
|
||||
corretamente (inspecionar no DevTools que os valores computados
|
||||
batem)
|
||||
- [ ] Classes utilitárias do Tailwind (`bg-primary`, `text-danger` etc)
|
||||
funcionam e refletem os tokens
|
||||
- [ ] `/diagnostico` mostra o retorno real de `GET /health` do backend
|
||||
(com o backend rodando local)
|
||||
- [ ] `npm run lint` roda sem erro
|
||||
- [ ] Estrutura de pastas idêntica à definida na seção 9 do schema de
|
||||
frontend
|
||||
@@ -0,0 +1,105 @@
|
||||
# Etapa 12 — Sistema de Design e Componentes Base
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Continuação do frontend do **SeConectai Vendas**. A Etapa 11 entregou o
|
||||
projeto Next.js configurado com Tailwind, tokens de design e estrutura
|
||||
de pastas. Nenhum componente de UI reutilizável existe ainda.
|
||||
|
||||
Referência obrigatória: seção 6 (tokens) e seção 7 (lista de
|
||||
componentes) do `10-frontend-schema-arquitetura.md`.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Construir a biblioteca de componentes base (`components/ui/`) que será
|
||||
usada por **todas** as telas de negócio das próximas etapas. Tudo aqui
|
||||
deve já nascer responsivo e acessível — as telas de negócio só vão
|
||||
compor esses componentes, não reimplementar comportamento responsivo
|
||||
caso a caso.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **Base a partir do shadcn/ui**
|
||||
- Instalar e configurar shadcn/ui, mas customizar cada componente
|
||||
usado para consumir os tokens do projeto (não deixar cores/spacing
|
||||
hardcoded vindos do template padrão).
|
||||
- Justificar no código (comentário curto) qualquer componente que
|
||||
fugir do padrão shadcn por necessidade específica do projeto.
|
||||
|
||||
2. **Componentes a construir** (todos em `components/ui/`, cada um com
|
||||
suas variantes documentadas via comentário ou arquivo `.stories`
|
||||
opcional):
|
||||
|
||||
- **Button**: variantes `primary` (usa `--color-primary`),
|
||||
`secondary`, `destructive`, `ghost`; tamanhos `sm`/`md`/`lg`; estado
|
||||
`loading` (spinner substituindo o label, sem mudar a largura do
|
||||
botão); estado `disabled`.
|
||||
- **Input / Textarea**: com label, texto de ajuda, estado de erro
|
||||
(borda + mensagem), prefixo/sufixo opcional (ex: "R$" para campos
|
||||
de valor).
|
||||
- **Select**: nativo estilizado ou baseado em Radix (via shadcn),
|
||||
com busca para listas longas (ex: seleção de cliente/produto).
|
||||
- **DatePicker**: seleção de data única e, quando necessário, período
|
||||
(usado nos filtros de dashboard/listagens).
|
||||
- **FormField**: wrapper que padroniza label + input + mensagem de
|
||||
erro + texto de ajuda — todo formulário do sistema deve usar esse
|
||||
wrapper, nunca montar label/erro manualmente.
|
||||
- **Table**: **componente central desta etapa**. Recebe colunas e
|
||||
dados de forma genérica (tipado com generics em TypeScript).
|
||||
Abaixo do breakpoint `md`, renderiza automaticamente como lista de
|
||||
**Cards empilhados** (cada linha vira um card com pares
|
||||
rótulo:valor, permitindo destacar 1–2 campos principais e colapsar
|
||||
o resto). Suporta: ordenação por coluna, estado de loading
|
||||
(skeleton), estado vazio (usa o `EmptyState`), paginação integrada.
|
||||
- **Modal / Sheet**: um único componente que se comporta como modal
|
||||
centralizado no desktop e como tela cheia (ou bottom sheet, definir
|
||||
e justificar qual) no mobile, controlado pelo mesmo breakpoint `md`.
|
||||
- **Toast**: sistema de notificação temporária (sucesso, erro, aviso,
|
||||
info), empilhável, com auto-dismiss configurável.
|
||||
- **Badge / StatusPill**: variantes semânticas mapeadas para os
|
||||
status de negócio já existentes no backend (`pendente`, `pago`,
|
||||
`atrasado`, `cancelado`, `ativo`, `inadimplente`, `suspenso`,
|
||||
`trial`, `confirmada`, `concluida`, `orcamento`) — cada status com
|
||||
cor e label em português já resolvidos aqui, para não repetir esse
|
||||
mapeamento em cada tela.
|
||||
- **Card**: contêiner base usado em dashboards e nas listas
|
||||
responsivas da Table.
|
||||
- **Pagination**: controles de página, compatível com os parâmetros
|
||||
de paginação da API do backend.
|
||||
- **EmptyState**: ilustração/texto + ação sugerida, usado em toda
|
||||
listagem vazia (ex: "Nenhum cliente cadastrado ainda" + botão
|
||||
"Cadastrar cliente").
|
||||
- **Skeleton**: blocos de carregamento reutilizáveis (linha de texto,
|
||||
card, linha de tabela).
|
||||
- **Tabs**: navegação em abas (usado, por exemplo, no detalhe de
|
||||
venda: Itens / Parcelas / Histórico).
|
||||
|
||||
3. **Acessibilidade (obrigatório, não opcional)**
|
||||
- Todos os componentes interativos com foco de teclado visível
|
||||
(`outline` customizado com a cor de foco do design system, não o
|
||||
padrão do navegador nem `outline: none` sem substituto).
|
||||
- Componentes baseados em Radix/shadcn já trazem boa parte da
|
||||
semântica ARIA — não remover isso ao customizar.
|
||||
- Respeitar `prefers-reduced-motion` em qualquer transição/animação.
|
||||
- Touch targets mínimos de 44x44px nos componentes interativos.
|
||||
|
||||
4. **Página de showcase**
|
||||
- Criar uma rota de desenvolvimento (ex: `/dev/componentes`, não
|
||||
exposta em produção) que renderiza todos os componentes acima com
|
||||
suas variantes, para revisão visual rápida em qualquer breakpoint
|
||||
sem precisar montar uma tela de negócio primeiro.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Todos os componentes listados existem, tipados em TypeScript, com
|
||||
as variantes descritas
|
||||
- [ ] `Table` alterna corretamente entre tabela (≥768px) e cards
|
||||
empilhados (<768px) na página de showcase
|
||||
- [ ] `Modal/Sheet` alterna corretamente entre modal centralizado
|
||||
(desktop) e tela cheia/bottom sheet (mobile)
|
||||
- [ ] `StatusPill` cobre todos os status de negócio listados, com cor e
|
||||
label em português
|
||||
- [ ] Navegação por teclado (Tab) percorre todos os componentes
|
||||
interativos da página de showcase com foco visível
|
||||
- [ ] Nenhum componente quebra ou tem overflow horizontal em 375px
|
||||
- [ ] Página de showcase acessível apenas em ambiente de desenvolvimento
|
||||
@@ -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
|
||||
@@ -0,0 +1,94 @@
|
||||
# Etapa 14 — Layout e Navegação (Master e Tenant)
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Continuação do frontend do **SeConectai Vendas**. Já existem: setup,
|
||||
componentes base, e autenticação/tema funcionando. Ainda não existe
|
||||
nenhum layout real das áreas autenticadas — as rotas de `/master` e
|
||||
`/app` só têm placeholders.
|
||||
|
||||
Referência obrigatória: seção 5 (navegação por área) do
|
||||
`10-frontend-schema-arquitetura.md`.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Construir o "casco" (shell) de navegação das duas áreas autenticadas —
|
||||
sidebar, topbar, drawer mobile, bottom tab bar — totalmente responsivo,
|
||||
que vai envolver todas as telas de negócio das próximas etapas.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **Layout master (`app/master/layout.tsx`)**
|
||||
- Desktop (`lg+`): sidebar fixa à esquerda (~240px) com: logo/marca
|
||||
do SeConectai Vendas no topo (identidade fixa do master, não
|
||||
whitelabel), lista de itens de menu com ícone + label, item ativo
|
||||
destacado, avatar + nome do admin master + botão de logout no
|
||||
rodapé.
|
||||
- Itens do menu master: Dashboard, Tenants, Planos, Faturas,
|
||||
Configuração Evolution API, Alertas (Templates/Logs),
|
||||
Configurações.
|
||||
- Topbar: breadcrumb da página atual + ícone de notificações (pode
|
||||
ficar como placeholder visual nesta etapa, funcionalidade real na
|
||||
Etapa 18/19) + busca rápida (input, funcionalidade real pode ficar
|
||||
para depois, mas o componente deve existir).
|
||||
- Mobile (abaixo de `md`): topbar fixa compacta (logo símbolo +
|
||||
hambúrguer + notificações) + drawer com o menu completo + bottom
|
||||
tab bar com os itens mais usados (definir 4 principais: Dashboard,
|
||||
Tenants, Faturas, Alertas — o resto entra em "Mais").
|
||||
|
||||
2. **Layout tenant (`app/app/layout.tsx`)**
|
||||
- Mesma estrutura de sidebar/topbar/drawer/bottom-nav do master, mas:
|
||||
- Logo e cor vêm do tema do tenant autenticado (usar o que foi
|
||||
resolvido na Etapa 13).
|
||||
- Itens do menu: Dashboard, Clientes, Produtos, Vendas,
|
||||
Recebimentos, WhatsApp, E-mail, Alertas, Equipe, Perfil.
|
||||
- Bottom tab bar mobile com 4 principais: Dashboard, Clientes,
|
||||
Vendas, Recebimentos — resto em "Mais".
|
||||
- Itens do menu visíveis conforme o papel do usuário logado (ex:
|
||||
"Equipe" só aparece para `tenant_admin`) — implementar o
|
||||
controle de visibilidade por `role` aqui, para ser reaproveitado
|
||||
em todas as telas.
|
||||
|
||||
3. **Componentes de layout (`components/layout/`)**
|
||||
- `Sidebar`: recebe a lista de itens de menu e o slot de rodapé
|
||||
(usuário) como props/children — não deve ter os itens hardcoded
|
||||
dentro dela, para poder ser reaproveitada entre master e tenant com
|
||||
conteúdo diferente.
|
||||
- `Topbar`: recebe breadcrumb e slots de ações (notificações, busca).
|
||||
- `Drawer`: menu deslizante mobile, fecha ao navegar ou ao tocar fora.
|
||||
- `BottomTabBar`: recebe até 4 itens fixos + item "Mais" que abre um
|
||||
sheet com o restante do menu.
|
||||
- `Breadcrumb`: gerado a partir da estrutura de rotas (pode ser
|
||||
manual por página nesta primeira versão, com nota no código sobre
|
||||
automatizar depois).
|
||||
|
||||
4. **Estado de navegação**
|
||||
- Sidebar colapsável (ícones apenas) no breakpoint `md`, com um botão
|
||||
para expandir/recolher manualmente também no desktop, se fizer
|
||||
sentido — decisão livre, mas documentar o comportamento escolhido.
|
||||
- Persistir a preferência de sidebar colapsada/expandida (ex: em
|
||||
cookie ou localStorage, não é dado sensível).
|
||||
|
||||
5. **Empty shells das páginas de negócio**
|
||||
- Cada rota de `/master/*` e `/app/*` já criada como placeholder na
|
||||
Etapa 11 deve agora estar **dentro** do layout correto (sidebar +
|
||||
topbar aplicados), ainda com conteúdo placeholder — só a moldura
|
||||
precisa estar pronta e correta aqui.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Layout master renderiza sidebar/topbar no desktop e
|
||||
drawer+bottom-nav no mobile, com os itens de menu corretos
|
||||
- [ ] Layout tenant renderiza com a cor/logo do tenant autenticado
|
||||
aplicada corretamente na sidebar/topbar
|
||||
- [ ] Item "Equipe" só aparece no menu do tenant para usuários
|
||||
`tenant_admin` (testar com usuário de outro papel)
|
||||
- [ ] Navegação entre itens do menu funciona e destaca corretamente o
|
||||
item ativo, tanto no desktop quanto no drawer/bottom-nav mobile
|
||||
- [ ] Drawer mobile fecha ao selecionar um item ou tocar fora dele
|
||||
- [ ] Bottom tab bar mostra os 4 itens definidos + "Mais" com o restante
|
||||
- [ ] Sidebar colapsável funciona no breakpoint `md` e a preferência do
|
||||
usuário é lembrada entre sessões
|
||||
- [ ] Todas as rotas do mapa de rotas abrem dentro do layout correto
|
||||
(nenhuma "solta" sem sidebar/topbar)
|
||||
- [ ] Testado em 375px, 768px e 1280px sem quebra de layout
|
||||
@@ -0,0 +1,99 @@
|
||||
# Etapa 15 — Área Master: Telas de Negócio
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Continuação do frontend do **SeConectai Vendas**. Já existem: setup,
|
||||
design system, autenticação/tema, e o layout/navegação da área master
|
||||
funcionando. Esta etapa implementa as telas reais dentro desse layout,
|
||||
consumindo os endpoints do painel master já prontos no backend (Etapas
|
||||
3 e 4 do backend).
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Todas as telas funcionais da área `/master`: dashboard, gestão de
|
||||
tenants, planos, faturas, configuração da Evolution API e templates/logs
|
||||
de alerta.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **`/master/dashboard`**
|
||||
- Cards de resumo (usando o componente `Card`/`StatCard`): total de
|
||||
tenants por status, MRR, total recebido no mês, total em aberto.
|
||||
- Gráfico simples (Recharts) de evolução de faturamento ou novos
|
||||
tenants nos últimos meses, se o backend expuser dado suficiente
|
||||
para isso — caso não exponha, usar só os cards de resumo e anotar a
|
||||
limitação.
|
||||
- Layout em grid (2–4 colunas no desktop, coluna única no mobile).
|
||||
|
||||
2. **`/master/tenants`**
|
||||
- Listagem usando o componente `Table` (vira cards no mobile
|
||||
automaticamente), colunas: nome, status (`StatusPill`), plano,
|
||||
data de criação. Busca por nome/documento, filtro por status,
|
||||
paginação.
|
||||
- Ação rápida por linha: ver detalhe, mudar status.
|
||||
- Botão "Novo tenant" levando para `/master/tenants/novo`.
|
||||
|
||||
3. **`/master/tenants/novo`**
|
||||
- Formulário de criação: dados cadastrais, seleção de plano
|
||||
(`Select`), dia de vencimento da mensalidade, dados do primeiro
|
||||
usuário `tenant_admin` (nome, e-mail, senha provisória — mostrar a
|
||||
senha gerada/informada em um `Toast`/modal de confirmação após
|
||||
criar, com aviso claro para copiar/repassar ao cliente).
|
||||
|
||||
4. **`/master/tenants/:id`**
|
||||
- Detalhe completo com `Tabs`: Dados cadastrais (editável), Faturas
|
||||
(lista de `tenant_faturas` desse tenant, com ação de marcar como
|
||||
paga), Uso (quantidade de usuários/customers/vendas — dados
|
||||
agregados do backend).
|
||||
- Ação de mudar status (`ativo`/`suspenso`/`cancelado`/`inadimplente`)
|
||||
com confirmação explícita (modal) antes de aplicar, já que afeta o
|
||||
login dos usuários do tenant.
|
||||
|
||||
5. **`/master/planos`**
|
||||
- CRUD simples em lista + modal de criação/edição (não precisa de
|
||||
página própria, dado o volume baixo de planos).
|
||||
- Impedir exclusão de plano em uso (o backend já bloqueia — o
|
||||
frontend deve mostrar a mensagem de erro retornada de forma clara,
|
||||
não apenas um erro genérico).
|
||||
|
||||
6. **`/master/faturas`**
|
||||
- Listagem consolidada de todas as `tenant_faturas`, filtros por
|
||||
status/tenant/período, ação de marcar como paga.
|
||||
- Botão de ação para disparar a geração de faturas do mês (endpoint
|
||||
manual do backend nesta fase) com confirmação antes de executar.
|
||||
|
||||
7. **`/master/evolution-config`**
|
||||
- Formulário de cadastro/edição da conexão (nome, URL base, API key —
|
||||
campo de senha/mascarado, nunca mostrar a key completa depois de
|
||||
salva).
|
||||
- Botão "Testar conexão" com feedback claro de sucesso/erro (`Toast`).
|
||||
|
||||
8. **`/master/alertas/templates`** e **`/master/alertas/logs`**
|
||||
- Templates: lista + editor de template (tipo, canal, assunto,
|
||||
corpo com suporte a inserir os placeholders disponíveis via um
|
||||
menu de ajuda ao lado do editor).
|
||||
- Logs: listagem com filtro por canal/status/período, mostrando o
|
||||
conteúdo enviado e o erro (se houver) ao expandir uma linha.
|
||||
|
||||
9. **`/master/configuracoes`**
|
||||
- Dados do próprio admin master (nome, e-mail), troca de senha.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Todas as telas listadas funcionam ponta a ponta com o backend real
|
||||
- [ ] Dashboard mostra números corretos comparados com dados de teste
|
||||
conhecidos
|
||||
- [ ] Criar tenant exibe claramente a senha provisória gerada, com aviso
|
||||
de que não será mostrada novamente
|
||||
- [ ] Mudar status de tenant exige confirmação explícita antes de
|
||||
aplicar
|
||||
- [ ] Erros de negócio retornados pela API (ex: exclusão de plano em
|
||||
uso, limite de instância) aparecem como mensagem clara para o
|
||||
usuário, não como erro genérico
|
||||
- [ ] API key da Evolution nunca aparece em texto completo na tela após
|
||||
salva
|
||||
- [ ] Editor de template mostra os placeholders disponíveis e insere
|
||||
corretamente no corpo da mensagem
|
||||
- [ ] Todas as listagens usam paginação, busca/filtro e estados de
|
||||
loading/vazio corretamente
|
||||
- [ ] Todas as telas testadas em 375px, 768px e 1280px
|
||||
@@ -0,0 +1,86 @@
|
||||
# Etapa 16 — Área Tenant: Dashboard, Clientes e Produtos
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Continuação do frontend do **SeConectai Vendas**. Já existem: setup,
|
||||
design system, autenticação/tema, layout/navegação e a área master
|
||||
completa. Esta etapa inicia as telas de negócio da área `/app` (o
|
||||
painel que os seus clientes usam), consumindo os endpoints das Etapas 5
|
||||
e 6 (parte de dashboard) do backend.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Dashboard inicial do tenant, e os cadastros de clientes (customers) e
|
||||
produtos/serviços — a base de dados que toda venda vai referenciar.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **`/app/dashboard`**
|
||||
- Cards de resumo: total recebido no mês, total a receber
|
||||
(pendente+atrasado, com o atrasado destacado visualmente, ex: cor
|
||||
de alerta), quantidade de vendas no mês.
|
||||
- Gráfico de resumo semanal/mensal de vendas (Recharts), consumindo
|
||||
as views de dashboard do backend.
|
||||
- Lista das próximas parcelas a vencer (top 5–10), com link direto
|
||||
para `/app/recebimentos`.
|
||||
- Grid responsivo: 2–3 colunas no desktop, coluna única no mobile,
|
||||
gráfico sempre com largura total.
|
||||
|
||||
2. **`/app/clientes`**
|
||||
- Listagem (`Table`, vira cards no mobile) com busca por
|
||||
nome/documento, filtro por ativo/inativo, paginação.
|
||||
- Colunas/cards mostrando: razão social, documento, telefone/e-mail,
|
||||
status.
|
||||
- Botão "Novo cliente" → `/app/clientes/novo`.
|
||||
|
||||
3. **`/app/clientes/novo` e `/app/clientes/:id`**
|
||||
- Formulário completo: dados cadastrais (razão social, nome
|
||||
fantasia, documento, e-mail, telefone/WhatsApp, endereço, cidade,
|
||||
UF, observações).
|
||||
- No detalhe (`:id`), usar `Tabs`: Dados cadastrais (editável),
|
||||
Contatos (CRUD aninhado — lista de `customer_contacts` com
|
||||
indicação clara de qual é o principal e ação de marcar
|
||||
principal), Histórico de vendas (lista somente leitura das vendas
|
||||
desse cliente, com link para o detalhe de cada venda — mesmo que a
|
||||
tela de vendas só seja construída na próxima etapa, deixar o link
|
||||
já apontando para a rota correta).
|
||||
- Ação de desativar (soft delete) com confirmação, mantendo o
|
||||
registro visível no histórico.
|
||||
|
||||
4. **`/app/produtos`**
|
||||
- Listagem com filtro por tipo (`produto`/`servico`) e por ativo,
|
||||
busca por nome/SKU.
|
||||
- Colunas/cards: nome, tipo (`StatusPill` ou badge simples), valor de
|
||||
venda, SKU, status.
|
||||
|
||||
5. **`/app/produtos/novo` e `/app/produtos/:id`**
|
||||
- Formulário: tipo (produto/serviço), nome, descrição, SKU (opcional,
|
||||
validar unicidade — mostrar erro claro se a API retornar conflito),
|
||||
valor de venda, valor de custo (opcional), unidade, flag
|
||||
"recorrente".
|
||||
- Ação de desativar (soft delete) com confirmação.
|
||||
|
||||
6. **Validação e limites de plano**
|
||||
- Ao tentar criar cliente ou produto além do limite do plano do
|
||||
tenant, a API retorna erro — o frontend deve mostrar essa mensagem
|
||||
de forma clara (ex: banner ou toast explicando o limite atingido),
|
||||
não travar silenciosamente o formulário.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Dashboard do tenant mostra números batendo com dados de teste
|
||||
conhecidos
|
||||
- [ ] CRUD completo de clientes funciona, incluindo contatos aninhados e
|
||||
regra de contato principal único
|
||||
- [ ] Histórico de vendas no detalhe do cliente lista corretamente
|
||||
(mesmo que a tela de destino ainda não exista até a próxima etapa)
|
||||
- [ ] CRUD completo de produtos/serviços funciona, incluindo validação
|
||||
de SKU duplicado
|
||||
- [ ] Tentar exceder limite do plano (clientes ou produtos) mostra
|
||||
mensagem clara ao usuário
|
||||
- [ ] Desativar cliente/produto pede confirmação e reflete corretamente
|
||||
na listagem (sai da lista de ativos, mas seria visível com filtro
|
||||
"inativos")
|
||||
- [ ] Todas as listagens com busca, filtro, paginação e estados de
|
||||
loading/vazio
|
||||
- [ ] Todas as telas testadas em 375px, 768px e 1280px
|
||||
@@ -0,0 +1,97 @@
|
||||
# Etapa 17 — Área Tenant: Vendas e Financeiro
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Continuação do frontend do **SeConectai Vendas**. Já existem: setup,
|
||||
design system, autenticação/tema, layout/navegação, área master
|
||||
completa, e clientes/produtos no painel do tenant. Esta é a etapa mais
|
||||
crítica do painel do tenant — o fluxo de vendas e o controle financeiro
|
||||
— consumindo os endpoints da Etapa 6 do backend.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Registro completo de vendas (com itens e parcelas), listagem e ação
|
||||
sobre recebimentos, e os dashboards financeiros/semana-mês.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **`/app/vendas`**
|
||||
- Listagem (`Table`) com filtro por status (`orcamento`,
|
||||
`confirmada`, `concluida`, `cancelada`), por cliente, por período
|
||||
de `data_venda`, paginação.
|
||||
- Colunas/cards: número da venda, cliente, valor total, status
|
||||
(`StatusPill`), data.
|
||||
- Botão "Nova venda" → `/app/vendas/nova`.
|
||||
|
||||
2. **`/app/vendas/nova`** — a tela mais complexa do projeto
|
||||
- Seleção de cliente (`Select` com busca, puxando de `/app/clientes`)
|
||||
— se o cliente não existir ainda, oferecer atalho para cadastrar
|
||||
rápido sem sair do fluxo (modal com o formulário mínimo de
|
||||
cliente).
|
||||
- Lista de itens da venda: adicionar produto/serviço (busca por
|
||||
nome/SKU), quantidade, valor unitário (pré-preenchido do catálogo,
|
||||
editável para casos de desconto pontual — deixar claro visualmente
|
||||
quando o valor foi alterado do catálogo). Cálculo automático do
|
||||
subtotal por item e do total geral, considerando o campo de
|
||||
desconto geral da venda.
|
||||
- Definição das parcelas: opção "gerar parcelas automaticamente"
|
||||
(informar número de parcelas e primeira data de vencimento, o
|
||||
sistema calcula o resto) ou "definir manualmente" (lista editável
|
||||
de valor+vencimento por parcela). Validação em tempo real: soma das
|
||||
parcelas precisa bater com o valor total da venda antes de permitir
|
||||
salvar (mostrar a diferença, se houver, de forma clara).
|
||||
- Layout responsivo: no desktop, itens da venda e resumo/parcelas
|
||||
podem ficar lado a lado (2 colunas); no mobile, tudo empilhado com
|
||||
o resumo total sempre visível (ex: barra fixa no rodapé mostrando o
|
||||
total atualizado enquanto o usuário edita os itens).
|
||||
- Salvar como `orcamento` ou já como `confirmada` (duas ações
|
||||
distintas, não um único botão "Salvar").
|
||||
|
||||
3. **`/app/vendas/:id`**
|
||||
- Detalhe com `Tabs`: Itens (somente leitura se a venda estiver
|
||||
`confirmada`/`concluida`, editável se `orcamento`), Parcelas (lista
|
||||
com status e ação de marcar como paga por parcela), Histórico
|
||||
(mudanças de status, se o backend expuser isso via `audit_logs`).
|
||||
- Ações de topo: mudar status (confirmar orçamento, cancelar venda —
|
||||
com confirmação explícita explicando que isso cancela as parcelas
|
||||
pendentes associadas).
|
||||
|
||||
4. **`/app/recebimentos`**
|
||||
- Listagem de parcelas (`sale_payments`) via a view/endpoint do
|
||||
backend, com filtro por status, por cliente, por período de
|
||||
vencimento. Parcelas atrasadas destacadas visualmente (cor de
|
||||
alerta) e, se possível, ordenadas por padrão com as mais urgentes
|
||||
no topo.
|
||||
- Ação "Marcar como pago" por linha, com seleção de forma de
|
||||
pagamento — se o backend suportar ação em lote, oferecer seleção
|
||||
múltipla de linhas com ação "Marcar selecionadas como pagas".
|
||||
|
||||
5. **Dashboards financeiros (complementando `/app/dashboard` da Etapa
|
||||
16, se ainda não coberto)**
|
||||
- Gráfico de resumo semanal e mensal lado a lado ou alternável (toggle
|
||||
de período), usando as views `vw_resumo_vendas_semanal` /
|
||||
`vw_resumo_vendas_mensal` do backend.
|
||||
- Bloco "Financeiro": total recebido, total a receber, total
|
||||
atrasado, com cores semânticas consistentes com o `StatusPill`.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Criar venda completa (cliente + itens + parcelas) funciona ponta a
|
||||
ponta e reflete corretamente no backend
|
||||
- [ ] Validação de soma das parcelas vs. valor total impede salvar
|
||||
quando não bate, com mensagem clara da diferença
|
||||
- [ ] Cadastro rápido de cliente dentro do fluxo de nova venda funciona
|
||||
sem perder o que já foi preenchido na venda
|
||||
- [ ] Venda confirmada não permite editar itens/valores na tela de
|
||||
detalhe (reflete a regra do backend)
|
||||
- [ ] Cancelar venda pede confirmação e reflete o cancelamento das
|
||||
parcelas pendentes na tela de recebimentos
|
||||
- [ ] Marcar parcela como paga atualiza corretamente o dashboard
|
||||
financeiro sem precisar recarregar a página manualmente
|
||||
(invalidação de cache do React Query)
|
||||
- [ ] Parcelas atrasadas visualmente destacadas na listagem de
|
||||
recebimentos
|
||||
- [ ] Barra de total fixa no mobile durante a montagem de uma venda
|
||||
funciona corretamente e não sobrepõe conteúdo importante
|
||||
- [ ] Todas as telas testadas em 375px, 768px e 1280px, com atenção
|
||||
especial à tela de nova venda (a mais densa de informação)
|
||||
@@ -0,0 +1,97 @@
|
||||
# Etapa 18 — Área Tenant: Integrações, Alertas, Equipe e Perfil
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Continuação do frontend do **SeConectai Vendas**. Já existem: setup,
|
||||
design system, autenticação/tema, layout/navegação, área master
|
||||
completa, e clientes/produtos/vendas/recebimentos no painel do tenant.
|
||||
Esta etapa fecha o painel do tenant com as telas de configuração:
|
||||
integrações de mensageria, templates/logs de alerta próprios do tenant,
|
||||
gestão da equipe e personalização whitelabel — consumindo os endpoints
|
||||
das Etapas 4, 7 e 8 do backend.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Telas de `/app/whatsapp`, `/app/email-config`, `/app/alertas/*`,
|
||||
`/app/equipe` e `/app/perfil`.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **`/app/whatsapp`**
|
||||
- Lista de instâncias WhatsApp do tenant (pode ser mais de uma,
|
||||
conforme limite do plano), com status (`desconectado`,
|
||||
`conectando`, `conectado`, `erro`) via `StatusPill`.
|
||||
- Ação "Nova instância" (respeitando limite do plano — mostrar
|
||||
mensagem clara se atingido).
|
||||
- Fluxo de conexão: ao criar/selecionar uma instância, mostrar o QR
|
||||
code retornado pela API (imagem), com polling automático do status
|
||||
a cada poucos segundos até detectar `conectado` (parar o polling
|
||||
nesse momento e mostrar sucesso).
|
||||
- Botão de teste de envio (número + mensagem) com feedback claro.
|
||||
- Ação de desconectar/remover instância, com confirmação.
|
||||
|
||||
2. **`/app/email-config`**
|
||||
- Toggle "Usar configuração padrão da plataforma" vs "Usar meu
|
||||
próprio SMTP" — ao desativar o padrão, exibir e exigir os campos de
|
||||
SMTP próprio.
|
||||
- Botão de teste de envio (e-mail de destino) com feedback claro.
|
||||
- Senha do SMTP: campo tipo password, nunca pré-preenchido com o
|
||||
valor real ao editar (mesma lógica de segurança da API key da
|
||||
Evolution na área master).
|
||||
|
||||
3. **`/app/alertas/templates`**
|
||||
- Mesma lógica de editor da Etapa 15 (master), mas aqui os templates
|
||||
são do tenant, com fallback visual indicando quando um tipo/canal
|
||||
ainda não tem template próprio e está usando o padrão da
|
||||
plataforma (ex: badge "usando padrão da plataforma" com opção de
|
||||
"criar meu próprio").
|
||||
|
||||
4. **`/app/alertas/logs`**
|
||||
- Listagem de `alert_logs` filtrada para os alertas enviados pelo
|
||||
tenant (para os próprios `customers` dele), com os mesmos filtros
|
||||
da tela master (canal, status, período) e expansão de linha para
|
||||
ver conteúdo enviado/erro.
|
||||
|
||||
5. **`/app/equipe`** (visível só para `tenant_admin`, conforme já
|
||||
controlado no layout da Etapa 14)
|
||||
- Listagem dos `tenant_users` do tenant, com papel (`role`) e status
|
||||
ativo/inativo.
|
||||
- Convite/criação de novo usuário: nome, e-mail, papel, senha
|
||||
provisória (mesma UX de exibir e avisar sobre a senha gerada, como
|
||||
na criação de tenant pelo master).
|
||||
- Ação de desativar usuário e de alterar papel.
|
||||
|
||||
6. **`/app/perfil`**
|
||||
- Dados da empresa (nome fantasia, razão social — parte editável
|
||||
dentro do que o backend permitir ao tenant alterar).
|
||||
- **Upload de logo**: componente de upload com preview imediato,
|
||||
validação de tipo/tamanho no client antes de enviar (espelhando as
|
||||
regras do backend: png/jpg/svg, até 2MB), e ação de remover logo
|
||||
(volta ao padrão da plataforma).
|
||||
- **Seletor de cor primária**: color picker, com preview ao vivo de
|
||||
como a cor fica aplicada nos componentes principais (ex: mostrar um
|
||||
botão de exemplo com a cor escolhida antes de salvar), incluindo o
|
||||
aviso de contraste automático descrito na Etapa 13.
|
||||
- Ao salvar, o tema da aplicação inteira (sidebar, botões) deve
|
||||
atualizar imediatamente, sem precisar recarregar a página.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Fluxo completo de conexão de instância WhatsApp funciona (criar →
|
||||
escanear QR → status muda para conectado automaticamente via
|
||||
polling)
|
||||
- [ ] Teste de envio de WhatsApp e de e-mail funcionam com feedback
|
||||
claro de sucesso/erro
|
||||
- [ ] Alternância entre SMTP próprio e padrão da plataforma funciona
|
||||
corretamente, exigindo campos quando aplicável
|
||||
- [ ] Templates do tenant mostram claramente quando estão usando
|
||||
fallback do padrão da plataforma
|
||||
- [ ] Logs de alerta do tenant mostram apenas os alertas dele
|
||||
(isolamento correto)
|
||||
- [ ] CRUD de equipe funciona e respeita a visibilidade só para
|
||||
`tenant_admin`
|
||||
- [ ] Upload de logo funciona com validação client-side e preview
|
||||
imediato
|
||||
- [ ] Alteração de cor primária reflete instantaneamente em toda a
|
||||
aplicação após salvar, sem reload manual
|
||||
- [ ] Todas as telas testadas em 375px, 768px e 1280px
|
||||
@@ -0,0 +1,98 @@
|
||||
# Etapa 19 — Polimento, Acessibilidade e Testes E2E
|
||||
|
||||
## Contexto do projeto
|
||||
|
||||
Etapa final do frontend do **SeConectai Vendas**. Todas as telas de
|
||||
negócio das áreas master e tenant já estão implementadas (Etapas 11–18).
|
||||
Esta etapa é uma auditoria completa e o fechamento com testes
|
||||
automatizados, antes de considerar o frontend pronto para produção.
|
||||
|
||||
## Objetivo desta etapa
|
||||
|
||||
Revisão sistemática de responsividade e acessibilidade em todas as
|
||||
telas, ajustes de performance, e uma suíte de testes E2E cobrindo os
|
||||
fluxos críticos do sistema.
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. **Auditoria de responsividade**
|
||||
- Percorrer **todas** as rotas do mapa de rotas (master e tenant) nos
|
||||
três breakpoints de referência (375px, 768px, 1280px) e registrar/
|
||||
corrigir qualquer:
|
||||
- overflow horizontal
|
||||
- texto cortado ou sobreposto
|
||||
- touch target menor que 44x44px em mobile
|
||||
- tabela que não virou card corretamente
|
||||
- modal que não se adaptou (tela cheia/bottom sheet) no mobile
|
||||
- Prestar atenção especial às telas mais densas: `/app/vendas/nova`,
|
||||
`/master/tenants/:id`, dashboards com gráficos.
|
||||
|
||||
2. **Auditoria de acessibilidade**
|
||||
- Rodar um checador automatizado (ex: axe-core) em todas as rotas
|
||||
principais e corrigir violações críticas e sérias.
|
||||
- Verificar manualmente: navegação completa por teclado (Tab/Shift+Tab)
|
||||
em pelo menos um fluxo completo por área (ex: criar um cliente
|
||||
inteiro só com teclado), foco visível em 100% dos elementos
|
||||
interativos, contraste de texto mínimo AA em todos os textos
|
||||
(incluindo sobre a cor primária dinâmica do tenant).
|
||||
- Confirmar que `prefers-reduced-motion` é respeitado em todas as
|
||||
transições/animações implementadas ao longo do projeto.
|
||||
- Textos alternativos em imagens relevantes (logo do tenant, ícones
|
||||
que carregam significado além do decorativo).
|
||||
|
||||
3. **Estados de loading, erro e vazio**
|
||||
- Conferir que **toda** listagem e todo formulário do sistema trata
|
||||
corretamente: carregando (skeleton), erro de rede/API (mensagem
|
||||
clara com ação de tentar novamente quando fizer sentido), e vazio
|
||||
(EmptyState com ação sugerida). Nenhuma tela pode ficar em branco
|
||||
silenciosamente em caso de erro.
|
||||
|
||||
4. **Performance**
|
||||
- Rodar Lighthouse (ou equivalente) nas rotas principais, mobile e
|
||||
desktop, e corrigir problemas de maior impacto (ex: imagens sem
|
||||
otimização, JS não utilizado sendo carregado antecipadamente,
|
||||
ausência de `next/image` onde aplicável).
|
||||
- Garantir `loading="lazy"` em imagens fora da dobra inicial (ex:
|
||||
logos em listagens longas, se aplicável).
|
||||
|
||||
5. **Testes E2E (Playwright ou Cypress — escolher um e justificar)**
|
||||
- Fluxo 1: login master → criar tenant → confirmar que o
|
||||
`tenant_admin` criado consegue logar.
|
||||
- Fluxo 2: login tenant → cadastrar cliente → cadastrar produto →
|
||||
criar venda com parcelas → marcar uma parcela como paga → conferir
|
||||
que o dashboard financeiro reflete o pagamento.
|
||||
- Fluxo 3: alteração de logo/cor no perfil do tenant e confirmação
|
||||
visual de que o tema mudou na sidebar.
|
||||
- Fluxo 4: tentativa de acesso não autenticado a rota protegida
|
||||
(`/app/dashboard` sem login) redireciona corretamente para
|
||||
`/login`.
|
||||
- Rodar a suíte pelo menos no viewport mobile e no desktop (Playwright
|
||||
permite configurar múltiplos projetos/viewports).
|
||||
|
||||
6. **Revisão final de conteúdo/copy**
|
||||
- Passar por todos os textos de botão, mensagem de erro, empty state
|
||||
e confirmação verificando: voz ativa, consistência de nome de ação
|
||||
(o botão "Salvar" deve gerar uma confirmação que também fala em
|
||||
"salvo", não "criado" ou outra variação), e nenhuma mensagem de
|
||||
erro genérica onde a API já fornece detalhe suficiente para ser
|
||||
específica.
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Nenhuma rota do mapa de rotas tem overflow horizontal em 375px,
|
||||
768px ou 1280px
|
||||
- [ ] Checador de acessibilidade automatizado sem violações críticas ou
|
||||
sérias nas rotas principais
|
||||
- [ ] Um fluxo completo (ex: cadastro de cliente) realizado do início ao
|
||||
fim apenas com teclado, com foco sempre visível
|
||||
- [ ] Contraste de texto validado sobre a cor primária dinâmica em pelo
|
||||
menos 3 tenants de teste com cores diferentes (incluindo uma cor
|
||||
clara, para forçar o ajuste automático de contraste)
|
||||
- [ ] Todas as listagens e formulários tratam loading/erro/vazio
|
||||
corretamente — testado forçando erro de rede manualmente
|
||||
- [ ] Lighthouse mobile e desktop nas rotas principais sem alertas de
|
||||
performance de alto impacto
|
||||
- [ ] Suíte de testes E2E dos 4 fluxos descritos passa em mobile e
|
||||
desktop
|
||||
- [ ] Revisão de copy concluída, sem mensagens de erro genéricas onde a
|
||||
API fornece detalhe específico
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user