|
|
@@ -15,13 +15,17 @@ frontend/src/
|
|
|
├── styles/ CSS global e variáveis de tema
|
|
|
├── utils/ Utilitários genéricos
|
|
|
└── views/ Páginas da aplicação
|
|
|
- ├── auth/ LoginView
|
|
|
+ ├── atendimentos/ AtendimentoView, AvaliacoesView, GoldenSetView, NaoResolvidosView, RankingAtendentesView
|
|
|
+ ├── auth/ LoginView
|
|
|
├── configuracoes/
|
|
|
- ├── conversas/ ConversasHistoricoView, ConversasPesquisarView
|
|
|
+ ├── conversas/ ConversasHistoricoView, ConversasPesquisarView, ConversasWhatsappView
|
|
|
+ ├── documentos/ DocumentosView, CarregarDocumentoView
|
|
|
├── pagina-inicial/
|
|
|
└── usuarios/
|
|
|
```
|
|
|
|
|
|
+Design system e componentes reutilizáveis em [components.md](components.md).
|
|
|
+
|
|
|
## 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`.
|
|
|
@@ -32,13 +36,24 @@ O Vue Router está configurado em `src/router/index.js`. Todas as rotas autentic
|
|
|
| `/` | `home` | `PaginaInicialView` | Autenticados |
|
|
|
| `/conversas/historico` | `conversas-historico` | `ConversasHistoricoView` | Autenticados |
|
|
|
| `/conversas/pesquisar` | `conversas-pesquisar` | `ConversasPesquisarView` | Autenticados |
|
|
|
+| `/conversas-whatsapp` | `conversas-whatsapp` | `ConversasWhatsappView` | 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`
|
|
|
+| `/usuarios` | `usuarios` | `UsuariosView` | Admin (`nivelMinimo`) |
|
|
|
+| `/atendimentos/avaliacoes` | `avaliacoes` | `AvaliacoesView` | Admin (`nivelMinimo`) |
|
|
|
+| `/atendimentos/nao-resolvidos` | `atendimentos-nao-resolvidos` | `NaoResolvidosView` | Admin (`nivelMinimo`) |
|
|
|
+| `/atendimentos/ranking-atendentes` | `ranking-atendentes` | `RankingAtendentesView` | Admin (`nivelMinimo`) |
|
|
|
+| `/atendimentos/:id` | `atendimento` | `AtendimentoView` | Admin (`nivelMinimo`) |
|
|
|
+| `/atendimentos/golden-set` | `golden-set` | `GoldenSetView` | Admin (`nivelMinimo`) |
|
|
|
+| `/documentos` | `documentos` | `DocumentosView` | Admin (`nivelMinimo`) |
|
|
|
+| `/documentos/carregar` | `documentos-carregar` | `CarregarDocumentoView` | Admin (`nivelMinimo`) |
|
|
|
+
|
|
|
+Todas as rotas usam lazy loading (`() => import(...)`) — nenhuma view é importada estaticamente no router.
|
|
|
+
|
|
|
+**Guard de rota** (`router.beforeEach`):
|
|
|
+- Usuário não autenticado tentando rota `requiresAuth` → redirecionado para `/login` (com `?redirect=` de volta)
|
|
|
+- Usuário autenticado tentando rota `guestOnly` (`/login`) → redirecionado para `/`
|
|
|
+- Usuário sem o `nivelMinimo` exigido pela rota → redirecionado para `/configuracoes`
|
|
|
+- Falha ao carregar um chunk lazy (deploy novo com o usuário na aba antiga) → tenta um reload automático da página uma vez; se falhar de novo, mostra um banner (`chunkLoadError`) em vez de loop
|
|
|
|
|
|
## Layout do sistema
|
|
|
|
|
|
@@ -49,29 +64,35 @@ O Vue Router está configurado em `src/router/index.js`. Todas as rotas autentic
|
|
|
|
|
|
## Estado da aplicação
|
|
|
|
|
|
-O frontend **não usa Pinia**. O estado é gerenciado por composables com padrão singleton:
|
|
|
+O frontend **não usa Pinia**. O estado é gerenciado por composables (`src/composables/`), a maioria 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
|
|
|
+- `useListaAvaliacoes` — instância por componente; estado compartilhado por `AvaliacoesView` e `NaoResolvidosView` (paginação, busca com debounce, sincronização com a query string)
|
|
|
+- `useConversas`, `useConversaEdicao`, `useWhatsappConexao`, `useDocumentos` — estado do chat de atendente (WhatsApp) e da tela de documentos, instância por componente
|
|
|
+- `useSearch`, `useToast`, `useUsers`, `useMenuUsuario`, `useSidebar`, `useTheme`, `useRouteLoading`, `useValorDebounced`, `useAsyncState` — instâncias por componente ou utilitários sem estado próprio compartilhado
|
|
|
|
|
|
-Consulte [composables.md](composables.md) para detalhes de cada um.
|
|
|
+Consulte [composables.md](composables.md) para detalhes de cada um (documenta os principais; nem todos os listados acima têm entrada própria lá).
|
|
|
|
|
|
## 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):
|
|
|
+Os arquivos em `src/api/` encapsulam as chamadas HTTP, um por domínio. Todos usam o `client.js` (que faz `fetch` com injeção de token e refresh automático). Referência de endpoints em [backend/docs/api.md](../../backend/docs/api.md):
|
|
|
|
|
|
```
|
|
|
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
|
|
|
+├── client.js Cliente HTTP com interceptor de auth e refresh automático (apiFetch, fetchAutenticado)
|
|
|
+├── auth.js loginRequest, logoutRequest, refreshTokenRequest, solicitarResetSenha
|
|
|
+├── chat.js sendChatStream, ingestDocuments, ingestFile, ingestUrl,
|
|
|
+│ search, listDocuments, deleteDocumentsBySource
|
|
|
+├── chatConversas.js CRUD de conversas do chat: listConversations, createConversation,
|
|
|
+│ getConversationMessages, updateConversationTitle, deleteConversation, exportConversation
|
|
|
+├── atendimentos.js sincronização, avaliação, golden set, ranking de atendentes e relatórios PDF
|
|
|
+├── conversas.js chat de atendente via WhatsApp: listarConversas, responderConversa, gerarSugestaoResposta, ...
|
|
|
+├── whatsappConexao.js statusWhatsapp
|
|
|
+└── users.js listUsers, createUser, updateUser, toggleUserStatus, reset de senha
|
|
|
```
|
|
|
|
|
|
-> 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`.
|
|
|
+> Chat, busca, ingest e documentos vivem em `chat.js` — não há `documents.js`/`ingest.js` separados. `conversations.js` não existe: o CRUD de conversas do chat é `chatConversas.js`, para não colidir com `conversas.js` (chat de atendente via WhatsApp, domínio diferente).
|
|
|
|
|
|
## Fluxo de autenticação no frontend
|
|
|
|
|
|
@@ -83,6 +104,8 @@ src/api/
|
|
|
5. O refresh proativo (scheduleProactiveRefresh) renova o token 60s antes de expirar
|
|
|
```
|
|
|
|
|
|
+Detalhes do composable em [composables.md](composables.md#useauth); fluxo e níveis de acesso do lado backend em [backend/docs/auth.md](../../backend/docs/auth.md).
|
|
|
+
|
|
|
## Tema (light/dark)
|
|
|
|
|
|
O tema é controlado pela classe `.dark` no elemento `<html>`. O componente `BotaoAlterarTema.vue` alterna entre os dois modos. Consulte [style.md](style.md) para o sistema de cores.
|