From b037512250756748790a763e16661b25fea5c34b Mon Sep 17 00:00:00 2001 From: Jonas Pacheco Date: Wed, 8 Apr 2026 15:25:28 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20resolve=20loading=20infinito=20na=20nave?= =?UTF-8?q?ga=C3=A7=C3=A3o=20entre=20m=C3=B3dulos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona ErrorBoundary para capturar erros do React.lazy() - LoadingFallback com timeout: aviso aos 3s, erro aos 10s - Atualiza documentação (SPEC_NAVBAR.md, AGENTS.md) O Suspense não captura falhas no lazy loading. Agora o ErrorBoundary envolve o Suspense e exibe UI de fallback quando há erros. --- .../page-2026-04-08T15-57-28-475Z.yml | 26 + .../page-2026-04-08T15-57-41-246Z.png | Bin 0 -> 26245 bytes .../page-2026-04-08T15-58-19-679Z.yml | 34 ++ .../page-2026-04-08T15-58-26-658Z.png | Bin 0 -> 23334 bytes .../page-2026-04-08T15-58-26-731Z.yml | 28 + .../page-2026-04-08T15-58-47-519Z.yml | 30 ++ .../page-2026-04-08T15-58-53-177Z.yml | 28 + .../page-2026-04-08T15-58-58-942Z.png | Bin 0 -> 23334 bytes AGENTS.md | 203 ++++++++ client/src/App.tsx | 182 ++++--- client/src/components/ErrorBoundary.tsx | 90 ++++ docs/SPEC_NAVBAR.md | 485 ++++++++++++++++++ 12 files changed, 1038 insertions(+), 68 deletions(-) create mode 100644 .playwright-mcp/page-2026-04-08T15-57-28-475Z.yml create mode 100644 .playwright-mcp/page-2026-04-08T15-57-41-246Z.png create mode 100644 .playwright-mcp/page-2026-04-08T15-58-19-679Z.yml create mode 100644 .playwright-mcp/page-2026-04-08T15-58-26-658Z.png create mode 100644 .playwright-mcp/page-2026-04-08T15-58-26-731Z.yml create mode 100644 .playwright-mcp/page-2026-04-08T15-58-47-519Z.yml create mode 100644 .playwright-mcp/page-2026-04-08T15-58-53-177Z.yml create mode 100644 .playwright-mcp/page-2026-04-08T15-58-58-942Z.png create mode 100644 AGENTS.md create mode 100644 client/src/components/ErrorBoundary.tsx create mode 100644 docs/SPEC_NAVBAR.md diff --git a/.playwright-mcp/page-2026-04-08T15-57-28-475Z.yml b/.playwright-mcp/page-2026-04-08T15-57-28-475Z.yml new file mode 100644 index 0000000..699f54c --- /dev/null +++ b/.playwright-mcp/page-2026-04-08T15-57-28-475Z.yml @@ -0,0 +1,26 @@ +- generic [ref=e2]: + - region "Notifications (F8)": + - list + - generic [ref=e5]: + - generic [ref=e6]: + - img "Arcadia" [ref=e7] + - heading "Arcádia Suite" [level=1] [ref=e8] + - generic [ref=e9]: + - tablist [ref=e10]: + - tab "Login" [selected] [ref=e11] + - tab "Criar Conta" [ref=e12] + - tabpanel "Login" [ref=e13]: + - generic [ref=e14]: + - generic [ref=e15]: + - generic [ref=e16]: Bem-vindo de volta + - generic [ref=e17]: Entre com suas credenciais para acessar o sistema + - generic [ref=e19]: + - generic [ref=e20]: + - text: Usuário + - textbox "Usuário" [ref=e21]: + - /placeholder: Digite seu usuário + - generic [ref=e22]: + - text: Senha + - textbox "Senha" [ref=e23]: + - /placeholder: Digite sua senha + - button "Entrar" [ref=e24] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-04-08T15-57-41-246Z.png b/.playwright-mcp/page-2026-04-08T15-57-41-246Z.png new file mode 100644 index 0000000000000000000000000000000000000000..563c83d481f9325b98b4b4817513b2fd045d61b4 GIT binary patch literal 26245 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%0A-&^Y6 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 UzJhbV4*UWkm9=h_DBgSeZ%<8V?EnA( literal 0 HcmV?d00001 diff --git a/.playwright-mcp/page-2026-04-08T15-58-26-731Z.yml b/.playwright-mcp/page-2026-04-08T15-58-26-731Z.yml new file mode 100644 index 0000000..96c6a88 --- /dev/null +++ b/.playwright-mcp/page-2026-04-08T15-58-26-731Z.yml @@ -0,0 +1,28 @@ +- generic [ref=e2]: + - region "Notifications (F8)": + - list + - generic [ref=e5]: + - generic [ref=e6]: + - img "Arcadia" [ref=e7] + - heading "Arcádia Suite" [level=1] [ref=e8] + - generic [ref=e9]: + - tablist [ref=e10]: + - tab "Login" [selected] [ref=e11] + - tab "Criar Conta" [ref=e12] + - tabpanel "Login" [ref=e13]: + - generic [ref=e14]: + - generic [ref=e15]: + - generic [ref=e16]: Bem-vindo de volta + - generic [ref=e17]: Entre com suas credenciais para acessar o sistema + - generic [ref=e19]: + - generic [ref=e20]: + - text: Usuário + - textbox "Usuário" [ref=e21]: + - /placeholder: Digite seu usuário + - text: admin + - generic [ref=e22]: + - text: Senha + - textbox "Senha" [ref=e23]: + - /placeholder: Digite sua senha + - text: admin + - button "Entrar" [ref=e24] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-04-08T15-58-47-519Z.yml b/.playwright-mcp/page-2026-04-08T15-58-47-519Z.yml new file mode 100644 index 0000000..8c8dee1 --- /dev/null +++ b/.playwright-mcp/page-2026-04-08T15-58-47-519Z.yml @@ -0,0 +1,30 @@ +- generic [ref=e2]: + - region "Notifications (F8)": + - list + - generic [ref=e5]: + - generic [ref=e6]: + - img "Arcadia" [ref=e7] + - heading "Arcádia Suite" [level=1] [ref=e8] + - generic [ref=e9]: + - tablist [ref=e10]: + - tab "Login" [selected] [ref=e11] + - tab "Criar Conta" [ref=e12] + - tabpanel "Login" [ref=e13]: + - generic [ref=e14]: + - generic [ref=e15]: + - generic [ref=e16]: Bem-vindo de volta + - generic [ref=e17]: Entre com suas credenciais para acessar o sistema + - generic [ref=e19]: + - generic [ref=e20]: + - text: Usuário + - textbox "Usuário" [ref=e21]: + - /placeholder: Digite seu usuário + - text: admin + - generic [ref=e22]: + - text: Senha + - textbox "Senha" [ref=e23]: + - /placeholder: Digite sua senha + - text: admin + - button "Entrando..." [disabled]: + - img + - text: Entrando... \ No newline at end of file diff --git a/.playwright-mcp/page-2026-04-08T15-58-53-177Z.yml b/.playwright-mcp/page-2026-04-08T15-58-53-177Z.yml new file mode 100644 index 0000000..96c6a88 --- /dev/null +++ b/.playwright-mcp/page-2026-04-08T15-58-53-177Z.yml @@ -0,0 +1,28 @@ +- generic [ref=e2]: + - region "Notifications (F8)": + - list + - generic [ref=e5]: + - generic [ref=e6]: + - img "Arcadia" [ref=e7] + - heading "Arcádia Suite" [level=1] [ref=e8] + - generic [ref=e9]: + - tablist [ref=e10]: + - tab "Login" [selected] [ref=e11] + - tab "Criar Conta" [ref=e12] + - tabpanel "Login" [ref=e13]: + - generic [ref=e14]: + - generic [ref=e15]: + - generic [ref=e16]: Bem-vindo de volta + - generic [ref=e17]: Entre com suas credenciais para acessar o sistema + - generic [ref=e19]: + - generic [ref=e20]: + - text: Usuário + - textbox "Usuário" [ref=e21]: + - /placeholder: Digite seu usuário + - text: admin + - generic [ref=e22]: + - text: Senha + - textbox "Senha" [ref=e23]: + - /placeholder: Digite sua senha + - text: admin + - button "Entrar" [ref=e24] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-04-08T15-58-58-942Z.png b/.playwright-mcp/page-2026-04-08T15-58-58-942Z.png new file mode 100644 index 0000000000000000000000000000000000000000..f73d1983d264e9bbc550e842827d1f480e5d4b52 GIT binary patch literal 23334 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 UzJhbV4*UWkm9=h_DBgSeZ%<8V?EnA( literal 0 HcmV?d00001 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..98d0181 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,203 @@ +# 🤖 Referência Rápida para Agentes - Arcádia Suite + +> Guia de referência para desenvolvimento autônomo no projeto Arcádia Suite + +--- + +## 📁 Documentação Técnica por Componente + +### Navegação (Navbar) +- **Especificação Completa:** [`docs/SPEC_NAVBAR.md`](docs/SPEC_NAVBAR.md) +- **Arquivo Fonte:** `client/src/components/Browser/BrowserFrame.tsx` +- **Hook de Tracking:** `client/src/hooks/use-navigation-tracking.ts` +- **Error Boundary:** `client/src/components/ErrorBoundary.tsx` (tratamento de erros lazy loading) + +### Banco de Dados (Schema) +- **Arquivo Principal:** `shared/schema.ts` (7.000+ linhas) +- **Tabelas Principais:** + - `users`, `profiles`, `roles` - Autenticação e RBAC + - `tenants`, `tenantUsers` - Multi-tenancy + - `workspacePages`, `pageBlocks` - Produtividade (estilo Notion) + - `conversations`, `messages` - Chat/Agente + - `whatsappSessions`, `whatsappMessages` - WhatsApp + - `crmPartners`, `crmContracts` - CRM + - `fiscalNcms`, `fiscalGruposTributacao` - Fiscal + - `retailStores`, `posSales`, `mobileDevices` - Retail + - `manusRuns`, `manusSteps` - Agente Manus + - `biDatasets`, `biCharts`, `biDashboards` - BI + +### Backend (API Routes) +- **Registro de Rotas:** `server/routes.ts` +- **Autenticação:** `server/auth.ts` +- **Agente Manus:** `server/manus/service.ts` + `server/manus/tools.ts` +- **WhatsApp:** `server/whatsapp/routes.ts` + `server/whatsapp/service.ts` +- **CRM:** `server/crm/routes.ts` +- **Fiscal:** `server/fisco/routes.ts` +- **Retail:** `server/retail/routes.ts` +- **Blackboard (Agentes):** `server/blackboard/routes.ts` + +### Frontend (Páginas) +- **Router:** `client/src/App.tsx` (inclui ErrorBoundary + Suspense) +- **Cockpit (Home):** `client/src/pages/Cockpit.tsx` +- **Agent:** `client/src/pages/Agent.tsx` +- **DevCenter:** `client/src/pages/DevCenter.tsx` +- **Crm:** `client/src/pages/Crm.tsx` +- **Fisco:** `client/src/pages/Fisco.tsx` +- **Retail:** `client/src/pages/ArcadiaRetail.tsx` +- **WhatsApp:** `client/src/pages/WhatsApp.tsx` +- **ErrorBoundary:** `client/src/components/ErrorBoundary.tsx` + +--- + +## 🏗️ Arquitetura do Sistema + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ CAMADA DE APRESENTAÇÃO │ +│ React 18 + TypeScript + Tailwind CSS + shadcn/ui │ +│ 66 páginas / Interface tipo browser com abas │ +└─────────────────────────────────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ CAMADA DE ORQUESTRAÇÃO │ +│ Express.js + Socket.IO + Manus Agent │ +│ API REST + WebSocket em tempo real │ +└─────────────────────────────────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ CAMADA DE INTELIGÊNCIA │ +│ FastAPI (Contábil 8003, BI 8004, Automação 8005) │ +│ OpenAI GPT-4o + LiteLLM Gateway + Ollama │ +└─────────────────────────────────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ CAMADA DE DADOS │ +│ PostgreSQL 16 + Drizzle ORM + pgvector │ +│ Session Store + Multi-tenant │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 🛠️ Stack Tecnológico + +| Camada | Tecnologia | +|--------|------------| +| **Frontend** | React 18, TypeScript, Tailwind CSS, shadcn/ui | +| **Backend** | Express.js, Socket.IO, Passport.js | +| **Banco** | PostgreSQL 16, Drizzle ORM, pgvector | +| **Python** | FastAPI (microserviços nas portas 8001-8005) | +| **IA** | OpenAI GPT-4o, LiteLLM, Ollama | +| **Deploy** | Docker Compose, Coolify, PM2 | + +--- + +## 🔧 Comandos Úteis + +```bash +# Desenvolvimento +npm run dev # Inicia servidor de desenvolvimento +npm run dev:client # Apenas frontend (porta 5000) + +# Banco de dados +npm run db:push # Aplica migrations Drizzle +npm run db:apply-rls # Aplica políticas RLS + +# Build +npm run build # Build para produção +npm run start # Inicia em produção + +# Docker +docker compose up -d # Sobe todos os serviços +docker compose --profile ai up # Sobe com IA (Ollama + LiteLLM) +``` + +--- + +## 📋 Convenções de Código + +### Nomenclatura +- **Componentes:** PascalCase (ex: `BrowserFrame.tsx`) +- **Hooks:** camelCase com prefixo `use` (ex: `useAuth.tsx`) +- **Utilitários:** camelCase (ex: `navigation-tracking.ts`) +- **Rotas API:** kebab-case (ex: `/api/whatsapp/connect`) + +### Estrutura de Pastas +``` +client/src/ + components/ # Componentes reutilizáveis + pages/ # Páginas da aplicação + hooks/ # Custom hooks + lib/ # Utilitários e configurações + +server/ + [modulo]/ # Um diretório por módulo + routes.ts # Rotas da API + service.ts # Lógica de negócio + storage.ts # Acesso a dados +``` + +--- + +## 🧪 Test IDs + +Sempre adicione `data-testid` em elementos interativos: + +```tsx + +``` + +--- + +## 📚 Documentação Adicional + +- **Documentação Técnica Completa:** [`DOCUMENTATION.md`](DOCUMENTATION.md) +- **Mapa do Sistema:** [`MAPA_SISTEMA_ARCADIA.md`](MAPA_SISTEMA_ARCADIA.md) +- **Contexto para Claude:** [`CLAUDE.md`](CLAUDE.md) +- **README:** [`README.md`](README.md) + +--- + +## 🆘 Precisa de Ajuda? + +1. Consulte a especificação técnica específica em `docs/` +2. Verifique exemplos similares no código existente +3. Siga os padrões já estabelecidos no projeto + +--- + +*Última atualização: 2026-04-08* + +--- + +## 🐛 Tratamento de Erros - Lazy Loading + +### Problema Resolvido: Loading Infinito na Navegação + +**Sintoma:** Ao clicar em itens da navbar, se a página tivesse erro (import quebrado, sintaxe inválida), o loading ficava infinito. + +**Causa:** `React.lazy()` falha silenciosamente e `Suspense` não tem como capturar o erro. + +**Solução:** + +1. **ErrorBoundary** (`client/src/components/ErrorBoundary.tsx`): + - Captura erros de renderização, incluindo lazy load + - Mostra UI de fallback com botão de retry + +2. **LoadingFallback com Timeout** (`client/src/App.tsx`): + - 3s: mensagem "Isso está demorando..." + - 10s: alerta amarelo com botão recarregar + +3. **Integração:** +```tsx + + }> + {/* rotas */} + + +``` diff --git a/client/src/App.tsx b/client/src/App.tsx index b1b4d76..ec334a1 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,5 +1,5 @@ import { Switch, Route, useLocation } from "wouter"; -import { lazy, Suspense, useEffect } from "react"; +import { lazy, Suspense, useEffect, useState } from "react"; import { queryClient } from "./lib/queryClient"; import { QueryClientProvider } from "@tanstack/react-query"; import { Toaster } from "@/components/ui/toaster"; @@ -10,6 +10,7 @@ import { ProtectedRoute } from "@/lib/protected-route"; import { CommandPalette } from "@/components/CommandPalette"; import { KnowledgeCollectorInit } from "@/components/KnowledgeCollectorInit"; import { OpenClawWidget } from "@/components/openclaw/OpenClawWidget"; +import { ErrorBoundary } from "@/components/ErrorBoundary"; import NotFound from "@/pages/not-found"; import AuthPage from "@/pages/auth-page"; @@ -72,13 +73,56 @@ const XosSupervisor = lazy(() => import("@/pages/XosSupervisor")); const XosReports = lazy(() => import("@/pages/XosReports")); const XosProtocols = lazy(() => import("@/pages/XosProtocols")); - function LoadingFallback() { + const [showSlowLoading, setShowSlowLoading] = useState(false); + const [showError, setShowError] = useState(false); + + useEffect(() => { + // Show "slow loading" message after 3 seconds + const slowTimer = setTimeout(() => setShowSlowLoading(true), 3000); + // Show error hint after 10 seconds + const errorTimer = setTimeout(() => setShowError(true), 10000); + + return () => { + clearTimeout(slowTimer); + clearTimeout(errorTimer); + }; + }, []); + return ( -
+

Carregando...

+ + {showSlowLoading && ( +

+ Isso está demorando mais que o esperado... +

+ )} + + {showError && ( +
+

+ A página pode ter um erro. Tente recarregar ou volte para a página anterior. +

+ +
+ )}
@@ -87,72 +131,74 @@ function LoadingFallback() { function Router() { return ( - }> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { const [, nav] = useLocation(); useEffect(() => nav("/soe"), []); return null; }} /> - - - - - - - - - - - - - - - - + + }> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { const [, nav] = useLocation(); useEffect(() => nav("/soe"), []); return null; }} /> + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + ); } diff --git a/client/src/components/ErrorBoundary.tsx b/client/src/components/ErrorBoundary.tsx new file mode 100644 index 0000000..8736ec5 --- /dev/null +++ b/client/src/components/ErrorBoundary.tsx @@ -0,0 +1,90 @@ +import { Component, ReactNode } from "react"; +import { AlertCircle, RefreshCw } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; + +interface Props { + children: ReactNode; + fallback?: ReactNode; +} + +interface State { + hasError: boolean; + error?: Error; +} + +export class ErrorBoundary extends Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error: Error): State { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { + console.error("[ErrorBoundary] Erro capturado:", error); + console.error("[ErrorBoundary] Info:", errorInfo); + } + + handleRetry = () => { + this.setState({ hasError: false, error: undefined }); + window.location.reload(); + }; + + handleGoHome = () => { + this.setState({ hasError: false, error: undefined }); + window.location.href = "/"; + }; + + render() { + if (this.state.hasError) { + // Fallback customizado ou padrão + if (this.props.fallback) { + return this.props.fallback; + } + + return ( +
+ + +
+ +
+ Ops! Algo deu errado + + Não foi possível carregar esta página. O módulo pode estar incompleto ou com erro. + +
+ + {this.state.error && ( +
+ {this.state.error.message} +
+ )} + +
+ + +
+
+
+
+ ); + } + + return this.props.children; + } +} diff --git a/docs/SPEC_NAVBAR.md b/docs/SPEC_NAVBAR.md new file mode 100644 index 0000000..1acfaf8 --- /dev/null +++ b/docs/SPEC_NAVBAR.md @@ -0,0 +1,485 @@ +# Especificação Técnica - Navbar do Arcádia Suite + +> **Versão:** 1.0 +> **Data:** 2026-04-08 +> **Arquivo Fonte:** `client/src/components/Browser/BrowserFrame.tsx` +> **Status:** Implementado e em produção + +--- + +## 1. Visão Geral + +A navbar do Arcádia Suite é uma barra de navegação compacta, horizontal e fixa no topo da tela. Ela implementa um padrão de "navegação por bookmarks" onde cada item representa um módulo principal do sistema. + +### 1.1 Objetivos +- Acesso rápido aos módulos principais +- Navegação intuitiva estilo "browser" +- Rastreamento de uso para analytics +- Suporte a múltiplos perfis de usuário + +### 1.2 Princípios de Design +- **Minimalista:** Apenas ícone + texto curto +- **Escalável:** Scroll horizontal permite muitos itens +- **Responsiva:** Adapta-se a diferentes telas +- **Consistente:** Cores e ícones padronizados + +--- + +## 2. Estrutura do Componente + +``` +BrowserFrame (Container) +└── CompactNavigationBar (Navbar principal) + ├── Área de Bookmarks (scroll horizontal) + │ └── BookmarkItem[] (itens de navegação) + └── Área do Usuário (fixa à direita) + └── UserDropdown (menu do usuário) +``` + +### 2.1 Hierarquia de Componentes + +```tsx +// BrowserFrame.tsx +interface BrowserFrameProps { + children: React.ReactNode; +} + +function CompactNavigationBar() { + // Hook de navegação + const [location, setLocation] = useLocation(); // wouter + const { user, logoutMutation } = useAuth(); + const { trackPageView } = useNavigationTracking(); + + // Handler de navegação + const navigateTo = (path: string, pageName: string) => { + trackPageView(pageName, path); + setLocation(path); + }; + + return ( +
+ {/* Bookmarks */} + {/* User Menu */} +
+ ); +} + +export function BrowserFrame({ children }: BrowserFrameProps) { + return ( +
+ +
{children}
+
+ ); +} +``` + +--- + +## 3. Especificação Visual + +### 3.1 Dimensões e Layout + +| Propriedade | Valor | Tailwind | +|-------------|-------|----------| +| Altura | 40px | `h-10` | +| Padding horizontal | 12px | `px-3` | +| Gap entre itens | 8px | `gap-2` | +| Tamanho do ícone | 16x16px | `w-4 h-4` | +| Tamanho do ícone interno | 10x10px | `w-2.5 h-2.5` | +| Padding do bookmark | 6px 8px | `px-2 py-1.5` | +| Border radius | 4px | `rounded` | + +### 3.2 Cores e Estilos + +``` +Fundo: bg-background (varia com tema claro/escuro) +Borda inferior: border-border +Texto: text-muted-foreground +Hover: hover:bg-muted +Sombra: shadow-xs +``` + +### 3.3 Estados dos Bookmarks + +| Estado | Estilo | +|--------|--------| +| **Default** | `text-muted-foreground` | +| **Hover** | `hover:bg-muted` + cursor pointer | +| **Ativo** | Não há estado visual de "ativo" (intencional) | + +--- + +## 4. Itens de Navegação (Bookmarks) + +### 4.1 Lista Completa de Itens + +| Ordem | Nome | Rota | Ícone | Cor do Gradient | Visibilidade | +|-------|------|------|-------|-----------------|--------------| +| 1 | Administração | `/admin` | Settings | slate-700 → slate-900 | Apenas admin | +| 2 | Início | `/` | Arcádia Icon | - (imagem) | Todos | +| 3 | Agent | `/agent` | Bot | primary → blue-600 | Todos | +| 4 | Inbox | `/xos/inbox` | MessageCircle | #00a884 → #25D366 | Todos | +| 5 | Automações | `/automations` | Zap | #c89b3c → #d4a94a | Todos | +| 6 | Insights | `/insights` | LayoutDashboard | #1f334d → #2d4a6f | Todos | +| 7 | Compass | `/compass` | Compass | #c89b3c → #1f334d | Todos | +| 8 | Produção | `/production` | Users | indigo-500 → indigo-700 | Todos | +| 9 | Suporte | `/support` | Ticket | rose-500 → rose-700 | Todos | +| 10 | ERP | `/erp` | Package | blue-600 → blue-800 | Todos | +| 11 | Retail | `/retail` | Store | cyan-500 → blue-600 | Todos | +| 12 | Plus | `/plus` | Layers | purple-500 → purple-700 | Todos | +| 13 | Fisco | `/fisco` | Receipt | emerald-600 → emerald-800 | Todos | +| 14 | Engenharia | `/engineering` | Compass | teal-500 → green-700 | Todos | + +### 4.2 Estrutura de um Bookmark + +```tsx +
navigateTo("/rota", "Nome")} + data-testid="bookmark-nome" +> + {/* Container do ícone com gradiente */} +
+ +
+ {/* Texto (oculto em mobile) */} + Nome +
+``` + +--- + +## 5. Menu do Usuário (Dropdown) + +### 5.1 Estrutura + +``` +[Avatar + Nome] ▼ + │ + ├── Informações do Usuário + │ ├── Nome completo + │ ├── @username + │ └── Badge "Administrador" (se aplicável) + │ + ├── Meu Perfil + │ + ├── Plataforma (apenas admin) + │ └── Centro de Desenvolvimento + │ + └── Sair (texto vermelho) +``` + +### 5.2 Componentes + +- **Trigger:** Botão com avatar circular + nome +- **Avatar:** Inicial do nome em círculo colorido (5x5) +- **Dropdown:** `DropdownMenu` do shadcn/ui +- **Largura:** 224px (`w-56`) + +--- + +## 6. Comportamento e Interações + +### 6.1 Fluxo de Navegação + +``` +┌─────────────────┐ +│ Usuário clica │ +│ em bookmark │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ trackPageView │ ← Registra no backend via POST /api/learning/navigation +│ (pageName, path)│ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ setLocation │ ← wouter atualiza URL +│ (path) │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ React.lazy() │ ← Code splitting carrega chunk +│ import() │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ │ ← Mostra LoadingFallback +│ fallback │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Página carrega │ ← Componente renderizado +│ e renderiza │ +└─────────────────┘ +``` + +### 6.2 Rastreamento (Analytics) + +```typescript +// use-navigation-tracking.ts +const trackPageView = (pageName: string, route?: string) => { + track({ + module: pageName, // Ex: "Agent", "Fisco" + action: "page_view", + metadata: { + route, // Ex: "/agent", "/fisco" + timestamp: "2026-04-08T15:30:00Z" + }, + }); +}; +``` + +**Debounce:** 2000ms para evitar spam de eventos + +### 6.3 Responsividade + +| Breakpoint | Comportamento | +|------------|---------------| +| **Mobile** (< 768px) | Texto dos bookmarks oculto (`hidden md:inline`), apenas ícones | +| **Desktop** (≥ 768px) | Texto visível ao lado do ícone | + +### 6.4 Scroll Horizontal + +- A área de bookmarks tem `overflow-x-auto` +- Scrollbar oculta (`scrollbar-hide`) +- Itens não quebram linha (`flex-shrink-0`) + +--- + +## 7. Dependências + +### 7.1 Bibliotecas + +```json +{ + "wouter": "^3.3.5", // Router + "lucide-react": "^0.545.0", // Ícones + "@radix-ui/react-dropdown-menu": "^2.1.16" // Dropdown +} +``` + +### 7.2 Hooks Customizados + +| Hook | Arquivo | Propósito | +|------|---------|-----------| +| `useLocation` | `wouter` | Navegação de rotas | +| `useAuth` | `@/hooks/use-auth` | Dados do usuário e logout | +| `useNavigationTracking` | `@/hooks/use-navigation-tracking` | Analytics | + +### 7.3 Componentes UI + +- `Button` (shadcn/ui) +- `DropdownMenu`, `DropdownMenuContent`, `DropdownMenuItem`, etc. (shadcn/ui) + +--- + +## 8. Test IDs (data-testid) + +Usados para testes automatizados: + +``` +bookmark-admin +bookmark-home +bookmark-agent +bookmark-xos-inbox +bookmark-automations +bookmark-insights +bookmark-compass +bookmark-production +bookmark-support +bookmark-erp +bookmark-retail +bookmark-plus +bookmark-fisco +bookmark-engineering +button-user-menu +button-logout +menu-development +``` + +--- + +## 9. Como Modificar + +### 9.1 Adicionar Novo Bookmark + +```tsx +// Em CompactNavigationBar, adicionar antes do
da área de bookmarks: + +
navigateTo("/nova-rota", "Nome")} + data-testid="bookmark-novo" +> +
+ +
+ Novo +
+``` + +### 9.2 Alterar Ordem + +Reorganizar os elementos `
` na ordem desejada dentro da área de bookmarks. + +### 9.3 Condicional por Permissão + +```tsx +{user?.role === "admin" && ( +
...
+)} + +// Ou por módulo permitido: +{(user as any)?.allowedModules?.includes("modulo") && ( +
...
+)} +``` + +--- + +## 10. Integração com Sistema + +### 10.1 Uso nas Páginas + +Todas as páginas que usam a navbar devem ser envolvidas por `BrowserFrame`: + +```tsx +// Exemplo: client/src/pages/Agent.tsx +import { BrowserFrame } from "@/components/Browser/BrowserFrame"; + +export default function Agent() { + return ( + +
+ {/* Conteúdo da página */} +
+
+ ); +} +``` + +### 10.2 Páginas que NÃO usam BrowserFrame + +- `AuthPage` (tela de login) +- `NotFound` (página 404) + +--- + +## 11. Considerações Técnicas + +### 11.1 Performance +- Code splitting via `React.lazy()` em todas as páginas +- Suspense com fallback de loading +- Debounce no rastreamento (2s) + +### 11.2 Acessibilidade +- `cursor-pointer` em todos os bookmarks +- Estrutura semântica do dropdown +- Contraste adequado nos ícones (branco sobre gradiente) + +### 11.3 Limitações Conhecidas +- Não há indicador visual de "página ativa" (design intencional) +- Scroll horizontal pode esconder itens em telas muito pequenas +- Não suporta drag-and-drop para reordenar + +### 11.4 Tratamento de Erros (Resolvido) + +**Problema:** Se uma página carregada via `React.lazy()` tivesse erro (import quebrado, sintaxe inválida), o `Suspense` ficava preso no estado de loading infinito. + +**Solução Implementada:** + +1. **ErrorBoundary** (`client/src/components/ErrorBoundary.tsx`): + - Captura erros em componentes filhos, incluindo falhas no lazy loading + - Exibe UI de fallback com detalhes do erro + - Botão "Tentar Novamente" para recarregar + +2. **LoadingFallback Aprimorado** (`client/src/App.tsx`): + - Após 3s: mostra mensagem "Isso está demorando mais que o esperado..." + - Após 10s: mostra alerta amarelo com botão de recarregar + +3. **Integração no Router**: +```tsx +function Router() { + return ( + {/* ← Captura erros */} + }> + + + {/* ... outras rotas ... */} + + + + ); +} +``` + +**Fluxo de Erro:** +``` +Usuário clica → lazy() falha → Suspense não resolve → ErrorBoundary captura + ↓ + LoadingFallback mostra + aviso após 3s/10s + ↓ + ErrorBoundary renderiza + UI de erro com retry +``` + +--- + +## 12. Diagrama de Sequência + +``` +┌────────┐ ┌─────────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ +│ Usuário│ │ Navbar │ │ wouter │ │ React │ │ Backend │ +└───┬────┘ └──────┬──────┘ └────┬─────┘ └────┬────┘ └────┬─────┘ + │ │ │ │ │ + │──clica─────────▶│ │ │ │ + │ │ │ │ │ + │ │──trackPageView────────────────────│──────────────▶│ + │ │ │ │ │ + │ │──setLocation───▶│ │ │ + │ │ │ │ │ + │ │ │──atualiza URL──│ │ + │ │ │ │ │ + │ │ │◀─URL changed───│ │ + │ │ │ │ │ + │ │ │──lazy import──▶│ │ + │ │ │ │ │ + │ │◀────────────────│──chunk loaded──│ │ + │ │ │ │ │ + │ │──renderiza nova página────────────▶│ │ + │ │ │ │ │ + │◀────────────────│ │ │ │ + │ │ │ │ │ +``` + +--- + +## 13. Changelog + +| Versão | Data | Alterações | +|--------|------|------------| +| 1.0 | 2026-04-08 | Especificação inicial criada | +| 1.1 | 2026-04-08 | Adicionado tratamento de erros (ErrorBoundary + LoadingFallback com timeout) | + +--- + +## 14. Referências + +- **Arquivo Fonte:** `client/src/components/Browser/BrowserFrame.tsx` +- **Hook de Tracking:** `client/src/hooks/use-navigation-tracking.ts` +- **Rotas:** `client/src/App.tsx` +- **Autenticação:** `client/src/hooks/use-auth.tsx` +- **UI Components:** `client/src/components/ui/` + +--- + +**Nota para Agentes:** +> Ao modificar a navbar, mantenha a consistência visual com os bookmarks existentes. Sempre adicione `data-testid` para testes e atualize esta especificação se houver mudanças significativas na estrutura ou comportamento.