# Arquitetura — Frontend ## Estrutura de pastas ``` frontend/src/ ├── api/ Funções de chamada HTTP (uma por domínio) ├── components/ Componentes Vue reutilizáveis │ ├── base/ Design system: BaseButton, BaseBadge, BaseModal │ └── skeletons/ Skeletons de carregamento ├── composables/ Estado e lógica reutilizável (useAuth, useChat, etc.) ├── docs/ Documentação do frontend ├── layout/ Layouts de página (LayoutSistema.vue) ├── router/ Configuração do Vue Router ├── styles/ CSS global e variáveis de tema ├── utils/ Utilitários genéricos └── views/ Páginas da aplicação ├── auth/ LoginView ├── configuracoes/ ├── conversas/ ConversasHistoricoView, ConversasPesquisarView ├── pagina-inicial/ └── usuarios/ ``` ## Roteamento O Vue Router está configurado em `src/router/index.js`. Todas as rotas autenticadas usam o meta `requiresAuth: true`, e a rota de login usa `guestOnly: true`. | Rota | Nome | Componente | Acesso | |---|---|---|---| | `/login` | `login` | `LoginView` | Apenas não autenticados | | `/` | `home` | `PaginaInicialView` | Autenticados | | `/conversas/historico` | `conversas-historico` | `ConversasHistoricoView` | Autenticados | | `/conversas/pesquisar` | `conversas-pesquisar` | `ConversasPesquisarView` | Autenticados | | `/configuracoes` | `configuracoes` | `ConfiguracoesView` | Autenticados | | `/usuarios` | `usuarios` | `UsuariosView` | Admin (nivel "3") | **Guard de rota:** - Usuário não autenticado tentando rota protegida → redirecionado para `/login` - Usuário autenticado tentando `/login` → redirecionado para `/` - Usuário de nível "1" tentando `/usuarios` → redirecionado para `/configuracoes` ## Layout do sistema `src/layout/LayoutSistema.vue` é o layout padrão de todas as páginas autenticadas. Ele contém: - Barra de navegação lateral com lista de conversas - Área principal de conteúdo (slot padrão) - Integração com `useChat` para carregar e exibir as conversas na sidebar ## Estado da aplicação O frontend **não usa Pinia**. O estado é gerenciado por composables com padrão singleton: - `useAuth` — singleton via closure (`session` é um `ref` no escopo do módulo) - `useChat` — singleton explícito (variável `singleton` no escopo do módulo) - `useSearch`, `useToast`, `useUsers` — instâncias por componente Consulte [composables.md](composables.md) para detalhes de cada um. ## Camada de API Os arquivos em `src/api/` encapsulam as chamadas HTTP. Todos usam o `client.js` (que faz `fetch` com injeção de token e refresh automático): ``` src/api/ ├── client.js Cliente HTTP com interceptor de auth e refresh automático ├── auth.js loginRequest, logoutRequest, refreshTokenRequest ├── chat.js sendChat, sendChatStream, search, ingestDocuments, │ ingestFile, ingestUrl, listDocuments, deleteDocumentsBySource ├── conversations.js listConversations, createConversation, ... └── users.js listUsers, createUser, updateUser, toggleUserStatus ``` > As funções de chat, busca, ingest e documentos vivem todas em `chat.js` — não há arquivos `documents.js` ou `ingest.js` separados. A função de ingest de texto é `ingestDocuments`. ## Fluxo de autenticação no frontend ``` 1. Ao montar o app, useAuth lê o token salvo em localStorage ou sessionStorage 2. O token é injetado no client.js via setAccessToken() 3. O wrapper de `fetch` em `client.js` captura respostas 401 e tenta refresh automático 4. Se o refresh falha, setAuthErrorCallback() é chamado → sessão limpa → redirect /login 5. O refresh proativo (scheduleProactiveRefresh) renova o token 60s antes de expirar ``` ## Tema (light/dark) O tema é controlado pela classe `.dark` no elemento ``. O componente `BotaoAlterarTema.vue` alterna entre os dois modos. Consulte [style.md](style.md) para o sistema de cores.