Documentation Index
Fetch the complete documentation index at: https://docs.domsoftware.com.br/llms.txt
Use this file to discover all available pages before exploring further.
Stack tecnológica
| Camada | Tecnologia |
|---|
| Framework | Next.js 16.0.7 (App Router) |
| Linguagem | TypeScript 5.x |
| UI / Estilos | Tailwind CSS v4.1, Radix UI, shadcn/ui pattern |
| Ícones | Lucide React |
| Animações | Framer Motion, tw-animate-css |
| Gráficos | Recharts |
| Notificações | Sonner (toast) |
| Estado global | Zustand v5 |
| Estado do servidor | TanStack Query v5 (React Query) |
| HTTP Client | Axios |
| Formulários | React Hook Form + Zod + @hookform/resolvers |
Estrutura de pastas
src/
├── app/ # Roteamento Next.js (App Router)
│ ├── (public)/ # Rotas públicas (login, landing)
│ ├── (protected)/ # Rotas autenticadas
│ │ ├── layout.tsx # Layout raiz protegido — auth guard + sidebar
│ │ ├── dashboard/
│ │ ├── products/
│ │ ├── inventory/
│ │ ├── orders/
│ │ ├── listings/
│ │ ├── integrations/
│ │ ├── imports/
│ │ └── ... # Demais módulos
│ ├── layout.tsx # Root layout (providers globais)
│ └── globals.css
│
├── components/ # Componentes compartilhados
│ ├── ui/ # Design system (Button, Input, Dialog, etc.)
│ ├── layout/ # Header, Sidebar, SidebarContext
│ ├── auth/ # RefreshTokenOverlay
│ └── integrations/
│
├── features/ # Lógica de negócio por domínio
│ ├── auth/
│ ├── catalog/
│ ├── inventory/
│ ├── listings/
│ ├── orders/
│ ├── imports/
│ ├── integrations/
│ ├── tenant/
│ └── ... # ~27 features no total
│
└── shared/ # Utilitários transversais
├── lib/
│ ├── axios.ts # Instância Axios com interceptors
│ └── utils.ts
├── providers/
│ ├── auth-provider.tsx # Silent refresh ao carregar a app
│ └── query-provider.tsx # QueryClient global
├── hooks/ # (reservado para hooks globais futuros)
└── types/ # Tipos TypeScript globais
Padrão de Feature
Cada domínio em src/features/ segue a mesma estrutura interna:
src/features/<nome>/
├── components/ # Componentes exclusivos desta feature (formulários, tabelas, cards)
├── hooks/ # Custom hooks — chamam os services e expõem para componentes
├── services/ # Chamadas Axios à API (única camada que usa HTTP)
├── store/ # Zustand store (se o domínio tiver estado global)
├── types/ # Interfaces e tipos TypeScript do domínio
└── schemas.ts # Schemas Zod de validação de formulários
Regra de ouro: componentes e hooks nunca chamam Axios. Só services/ faz chamadas HTTP.
Autenticação e Sessão
Fluxo de tokens
Usuário faz login
│
▼
POST /auth/login
│
├── accessToken (JWT, memória — Zustand)
└── refreshToken (HttpOnly cookie — automático)
O accessToken nunca é salvo em localStorage. Fica exclusivamente no Zustand (useAuthStore) em memória.
Silent Refresh (ao recarregar a página)
Quando o usuário recarrega (F5), o Zustand é reiniciado e o accessToken é perdido. O AuthProvider e o ProtectedLayout detectam esse estado e automaticamente chamam POST /auth/refresh usando o cookie HttpOnly:
F5 / Recarregar
│
▼
ProtectedLayout.initAuth()
│
├── authApi.refresh() → POST /auth/refresh (cookie enviado automaticamente)
│ │
│ ├── Sucesso: login() no Zustand + loadTenant()
│ └── Falha: logout() + redirect para /login?redirect=<pathname>
│
└── Mostra overlay de loading durante a hidratação
Interceptor Axios (src/shared/lib/axios.ts)
Toda requisição passa pelo interceptor que:
- Injeta
Authorization: Bearer <accessToken> no header.
- Injeta
x-tenant-id: <tenantId> no header.
- Se receber
401, tenta renovar o token automaticamente via /auth/refresh.
- Enquanto renova, coloca requisições paralelas em fila e as reexecuta após sucesso.
- Se o refresh falhar, chama
logout() e a fila de requisições é rejeitada.
Proteção de rotas
Todas as rotas em app/(protected)/** requerem autenticação. O ProtectedLayout redireciona para /login se o usuário não estiver autenticado após a tentativa de silent refresh.
Estado Global (Zustand)
| Store | Localização | Responsabilidade |
|---|
useAuthStore | features/auth/store/auth-store | user, accessToken, isRefreshing, logout |
useTenantStore | features/tenant/store/tenant-store | Dados do tenant ativo, loadTenant() |
Os stores são inicializados sem persistência em localStorage. A persistência é feita via cookie do refresh token.
Fetching de dados (TanStack Query)
O QueryProvider está no root layout. Toda busca de dados de servidor usa useQuery e mutações usam useMutation, sempre encapsulados em custom hooks dentro de features/<nome>/hooks/.
Convenção:
// features/products/hooks/useProducts.ts
export function useProducts(filters: ProductFilters) {
return useQuery({
queryKey: ['products', filters],
queryFn: () => productService.list(filters),
})
}
Paginação: Todos os endpoints usam cursor-based pagination. Nunca implemente offset.
- React Hook Form gerencia o estado dos formulários.
- Zod valida os dados (schemas em
features/<nome>/schemas.ts).
- A validação no frontend é limitada a UX e campos obrigatórios. Regras de negócio vêm do backend via resposta da API.
Convenções de código
| O que | Convenção |
|---|
| Diretórios | kebab-case |
| Componentes | PascalCase.tsx |
| Hooks / Services | camelCase.ts (ex: useProducts.ts, productService.ts) |
| Tipos | PascalCase (ex: Product, ProductResponse) |
'use client' | Apenas em leaf components (formulários, tabelas, interatividade) |
| Axios direto | ❌ Nunca em componentes ou hooks. Apenas em services/ |
| Estado global ad-hoc | ❌ Nunca use window, localStorage, ou singletons implícitos |
Módulos do frontend
Os 27 domínios em src/features/ correspondem às seguintes áreas do sistema:
| Feature | Descrição |
|---|
auth | Login, logout, sessão |
catalog | Catálogo de produtos |
products | Gestão de produtos |
products-dashboard | Dashboard de produtos |
inventory | Controle de estoque |
listings | Anúncios dos marketplaces |
integrations | Conexões OAuth com marketplaces |
imports | Importação de NF-e |
orders | Gestão de pedidos |
orders-dashboard | Dashboard de pedidos |
financial | Módulo financeiro |
fiscal | Módulo fiscal |
logistics | Logística |
dispatch | Expedição |
returns | Devoluções |
suppliers | Fornecedores |
partners | Parceiros |
brands | Marcas |
registries | Cadastros gerais |
tenant | Dados e configurações do tenant |
organization | Organização / empresa |
subscription/subscriptions | Planos e assinaturas |
plans | Planos disponíveis |
social-catalogs | Catálogos sociais |
social-catalogs-dashboard | Dashboard de catálogos sociais |
Variáveis de ambiente
| Variável | Obrigatória | Descrição |
|---|
NEXT_PUBLIC_API_URL | ✅ | URL base da API backend (ex: https://api.omnidom.com) |
NEXT_PUBLIC_APP_NAME | | Nome exibido na interface (padrão: Hub Marketplace) |
Configure em .env.local para desenvolvimento local. Em produção, configure no serviço de hospedagem (Vercel, etc.).