sistema-de-chamados/agents.md
rever-tecnologia 01b7103200 docs: registrar contato principal
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-10-06 09:09:42 -03:00

392 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Plano de Desenvolvimento - Sistema de Chamados
## Meta imediata
Construir o nucleo de tickets compartilhado entre web e desktop (Tauri), garantindo base solida para canais, SLAs e automacoes futuras.
### Contato principal
- **Esdras Renan** — monkeyesdras@gmail.com
## Fase A - Fundamentos da plataforma
1. **Scaffold e DX**
- Criar projeto Next.js (App Router) com Typescript, ESLint, Tailwind, shadcn/ui.
- Configurar alias de paths, lint/prettier opinativo.
- Ajustar `globals.css` para tokens de cor/tipografia conforme layout base.
2. **Design system inicial**
- Importar componentes `dashboard-01` e `sidebar-01` via shadcn.
- Ajustar paleta (tons de cinza + destaque primario) e tipografia (Inter/Manrope).
- Implementar layout shell (sidebar + header) reutilizavel.
3. **Autenticacao placeholder**
- Configurar stub de sessao (cookie + middleware) para navegacao protegida.
### Status da fase
- OK Scaffold Next.js + Tailwind + shadcn/ui criado em `web/`.
- OK Layout base atualizado (sidebar, header, cards, grafico) com identidade da aplicacao.
- OK Auth placeholder via cookie + middleware e bootstrap de usuario no Convex.
## Fase B - Nucleo de tickets
1. **Modelagem compartilhada**
- Definir esquema Prisma para Ticket, TicketEvent, User (minimo), Queue/View.
- Publicar Zod schemas/Types para uso no frontend.
2. **Fluxo principal**
- Pagina `tickets` com tabela (TanStack) suportando filtros basicos.
- Pagina de ticket com timeline de eventos/comentarios (dados mockados).
- Implementar modo play preliminar (simula proxima tarefa da fila).
3. **Mutations**
- Formulario de criacao/edicao com validacao.
- Comentarios publico/privado (UX + componentes).
### Status parcial
- OK `prisma/schema.prisma` criado com entidades centrais (User, Team, Ticket, Comment, Event, SLA).
- OK Schemas Zod e mocks compartilhados em `src/lib/schemas` e `src/lib/mocks`.
- OK Paginas `/tickets`, `/tickets/[id]` e `/play` prontas com componentes dedicados (filtros, tabela, timeline, modo play).
- OK Integração com backend Convex (consultas/mutações + file storage). Prisma mantido apenas como referência.
## Fase C - Servicos complementares (posterior)
- SLAs (BullMQ + Redis), notificacoes, ingest de e-mail, portal cliente, etc.
## Backlog imediato
- [x] Expor portal do cliente com listagem de tickets filtrada por `viewerId` (Convex + UI)
- [x] Completar painel administrativo (times, filas, campos e SLAs) com RBAC server/client
- [ ] Finalizar sincronização Better Auth ↔ Convex para resets de senha e revogações automáticas de convites
- [ ] Expandir suite de testes (UI + Convex) cobrindo guardas, relatórios e mapeadores críticos
- [x] Implementar fluxo completo de convites (criação, envio, revogação e aceite) para administradores
- [ ] Habilitar ações avançadas para agentes (edição de categorias, reassigação rápida) com as devidas permissões
- [ ] Integrar campos personalizados e categorias dinâmicas nos formulários de criação/edição de tickets
### Iniciativa atual — Autenticação real e personas
- [x] Migrar placeholder para Better Auth + Prisma (handlers Next, cliente React e sync Convex).
- [x] Expor roles (`admin`, `agent`, `customer`) e aplicar guardas (`requireUser/Staff/Admin/Customer`) no Convex.
- [x] Ajustar middleware e componentes para usar `viewerId`/`actorId`, evitando vazamento de dados entre tenants.
- [x] Criar portal do cliente para abertura/consulta de chamados e comentários públicos.
- [x] Consolidar painel administrativo (times, filas, campos e SLAs) com UI protegida por RBAC completo.
- [x] Entregar fluxo de convites Better Auth (criação, envio, revogação) e gerenciamento de agentes.
- [ ] Unificar ciclo de vida de credenciais (reset de senha, expiração automática e reenvio de convites).
## Proximas entregas sugeridas
1. Consolidar onboarding/offboarding de agentes com resets de senha, reenvio automático e auditoria de convites Better Auth.
2. Expor categorias, subcategorias e campos personalizados dinamicamente nas telas de criação/edição de tickets (web e desktop).
3. Definir permissões intermediárias para agentes (edição limitada de categorias/campos) e refletir no Convex.
4. Expandir relatórios operacionais (workSummary, métricas por canal/categoria) usando os novos campos personalizados.
5. Automatizar pipeline CI (lint + vitest) integrando checagens obrigatórias antes de merge.
## Acompanhamento
Atualizar este arquivo a cada marco relevante (setup concluido, nucleo funcional, etc.).
---
# Guia do Projeto (para agentes e contribuidores)
Este repositório foi atualizado para usar Convex como backend em tempo real para o núcleo de tickets. Abaixo, um guia prático conforme o padrão de AGENTS.md para orientar contribuições futuras.
## Decisões técnicas atuais
- Backend: Convex (funções + banco + storage) em `web/convex/`.
- Esquema: `web/convex/schema.ts`.
- Tickets API: `web/convex/tickets.ts` (list/getById/create/addComment/updateStatus/playNext).
- Upload de arquivos: `web/convex/files.ts` (Convex Storage).
- Filas: `web/convex/queues.ts` (resumo por fila).
- Seed/bootstrap: `web/convex/seed.ts`, `web/convex/bootstrap.ts`.
- Autenticação: Better Auth + Prisma (SQLite) com roles (`admin`, `agent`, `customer`) sincronizadas com Convex
- Login: `web/src/app/login/page.tsx` + `web/src/components/login/login-form.tsx`
- Middleware e guards: `web/middleware.ts`, helpers em `web/src/lib/auth{,z, -server}.ts`
- Cliente React: `web/src/lib/auth-client.tsx` (sincroniza sessão Better Auth ↔ Convex, expõe helpers de role)
- Frontend (Next.js + shadcn/ui)
- Páginas principais: `/tickets`, `/tickets/[id]`, `/tickets/new`, `/play`.
- UI ligada ao Convex com `convex/react`.
- Toasts: `sonner` via `Toaster` em `web/src/app/layout.tsx`.
- Mapeamento/validação de dados
- Convex retorna datas como `number` (epoch). A UI usa `Date`.
- Sempre converter/validar via Zod em `web/src/lib/mappers/ticket.ts`.
- Não retornar `Date` a partir de funções do Convex.
- Prisma: mantido apenas como referência de domínio (não é fonte de dados ativa).
## Como rodar
- Prérequisitos: Node LTS + pnpm.
- Passos:
- `cd web && pnpm i`
- `pnpm convex:dev` (mantém gerando tipos e rodando backend dev)
- Criar `.env.local` com `NEXT_PUBLIC_CONVEX_URL=<url exibida pelo convex dev>`
- Em outro terminal: `pnpm dev`
- Login em `/login`; seed opcional em `/dev/seed`.
## Convenções de código
- Não use `Date` em payloads do Convex; use `number` (epoch ms).
- Normalize dados no front via mappers Zod antes de renderizar.
- UI com shadcn/ui; priorize componentes existentes e consistência visual.
- Labels e mensagens em PTBR (status, timeline, toasts, etc.).
- Atualizações otimistas com rollback em erro + toasts de feedback.
- Comentários de supressão: prefira `@ts-expect-error` com justificativa curta para módulos gerados do Convex; evite `@ts-ignore`.
## Estrutura útil
- `web/convex/*` — API backend Convex.
- `web/src/lib/mappers/*` — Conversores server→UI com Zod.
- `web/src/components/tickets/*` — Tabela, filtros, detalhe, timeline, comentários, play.
## Scripts (pnpm)
- `pnpm convex:dev` — Convex (dev + geração de tipos)
- `pnpm dev` — Next.js (App Router)
- `pnpm build` / `pnpm start` — build/produção
## Backlog imediato (próximos passos)
- Form “Novo ticket” em Dialog shadcn + React Hook Form + Zod + toasts.
- Atribuição/transferência de fila no detalhe (selects com update otimista).
- Melhorias de layout adicionais no painel “Detalhes” (quebras, largura responsiva) e unificação de textos PTBR.
- Testes unitários dos mapeadores com Vitest.
## Checklist de PRs
- [ ] Funções Convex retornam apenas tipos suportados (sem `Date`).
- [ ] Dados validados/convertidos via Zod mappers antes da UI.
- [ ] Textos/labels em PTBR.
- [ ] Eventos de UI com feedback (toast) e rollback em erro.
- [ ] Documentação atualizada se houver mudanças em fluxo/env.
---
## Próximas Entregas (Roadmap detalhado)
1) UX/Visual (shadcn/ui)
- Padronizar cartões em todas as telas (Play, Visualizações) com o mesmo padrão aplicado em Conversa/Detalhes/Timeline (bordas, sombra, paddings).
- Aplicar microtipografia consistente: headings H1/H2, tracking, tamanhos, cores em PTBR.
- Skeletons de carregamento nos principais painéis (lista de tickets, recentes, play next).
- Melhorar tabela: estados hover/focus, ícones de canal, largura de colunas previsível e truncamento.
2) Comentários e anexos
- Dropzone também no “Novo ticket” (já implementado) com registro de comentário inicial e anexos.
- Grid de anexos com miniaturas e legenda; manter atributo `download` com o nome original.
- Preview em modal para imagens (feito) e suporte a múltiplas linhas no grid.
- Botão para copiar link de arquivo (futuro, usar URL do storage).
3) Timeline e eventos
- Mensagens amigáveis em PTBR (feito para CREATED/STATUS/ASSIGNEE/QUEUE).
- Incluir sempre `actorName`/`actorAvatar` no payload; evitar JSON cru na UI.
- Exibir avatar e nome do ator nas entradas (parcialmente feito).
4) Dados e camada Convex
- Sempre retornar datas como `number` (epoch) e converter no front via mappers Zod.
- Padronizar import do Convex com `@/convex/_generated/api` (alias criado).
- Evitar `useQuery` com args vazios — proteger chamadas (gates) e, quando necessário, fallback de mock para IDs `ticket-*`.
5) Autenticação / Sessão (placeholder)
- Cookie `demoUser` e bootstrap de usuário no Convex (feito). Trocar por Auth.js/Clerk quando for o momento.
6) Testes
- Vitest configurado; adicionar casos para mapeadores (já iniciado) e smoke tests básicos de páginas.
- Não usar Date em assertions de payload — sempre comparar epoch ou `instanceof Date` após mapeamento.
7) Acessibilidade e internacionalização
- Labels e mensagens 100% em PTBR; evitar termos como `QUEUE_CHANGED` na UI.
- Navegação por teclado em Dialogs/Selects; aria-labels em botões de ação.
8) Observabilidade (posterior)
- Logs de evento estruturados no Convex; traces simples no client para ações críticas.
---
## Endpoints Convex (resumo)
- `tickets.list({ tenantId, status?, priority?, channel?, queueId?, search?, limit? })`
- `tickets.getById({ tenantId, id })`
- `tickets.create({ tenantId, subject, summary?, priority, channel, queueId?, requesterId })`
- `tickets.addComment({ ticketId, authorId, visibility, body, attachments?[] })`
- `tickets.updateStatus({ ticketId, status, actorId })` — gera evento com `toLabel` e `actorName`.
- `tickets.changeAssignee({ ticketId, assigneeId, actorId })` — gera evento com `assigneeName`.
- `tickets.changeQueue({ ticketId, queueId, actorId })` — gera evento com `queueName`.
- `tickets.playNext({ tenantId, queueId?, agentId })` — atribui ticket e registra evento.
- `tickets.updatePriority({ ticketId, priority, actorId })` — altera prioridade e registra `PRIORITY_CHANGED`.
- `tickets.remove({ ticketId, actorId })` — remove ticket, eventos e comentários (tenta excluir anexos do storage).
- `queues.summary({ tenantId })`
- `files.generateUploadUrl()` — usar via `useAction`.
- `users.ensureUser({ tenantId, email, name, avatarUrl?, role?, teams? })`
Observações:
- Não retornar `Date` nas funções Convex; usar `number` e converter na UI com os mappers em `src/lib/mappers`.
- Evitar passar `{}` para `useQuery` — args devem estar definidos ou a query não deve ser invocada.
---
## Padrões de Código
- UI: shadcn/ui (Field, Dialog, Select, Badge, Table, Spinner) + Tailwind.
- Dados: Zod para validação; mappers para converter server→UI (epoch→Date, null→undefined).
- Texto: PTBR em labels, toasts e timeline.
- UX: updates otimistas + toasts (status, assignee, fila, comentários).
- Imports do Convex: sempre `@/convex/_generated/api`.
---
## Como abrir PR
- Crie uma branch descritiva (ex.: `feat/tickets-attachments-grid`).
- Preencha a descrição com: contexto, mudanças, como testar (pnpm scripts), screenshots quando útil.
- Checklist:
- [ ] Sem `Date` no retorno Convex.
- [ ] Labels PTBR.
- [ ] Skeleton/Loading onde couber.
- [ ] Mappers atualizados se tocar em payloads.
- [ ] AGENTS.md atualizado se houver mudança de padrões.
---
## Atualizações recentes (dez/2025)
- RBAC do Convex reforçado: `tickets.list`, `tickets.getById`, `workSummary` e mutações sensíveis (`changeQueue`, `updateCategories`, `startWork/pauseWork`, `updatePriority`) agora exigem `viewerId/actorId` e validam `requireStaff` com `tenantId`.
- Componentes de tickets (tabela, painel de recentes, play next, cabeçalho/detalhe) passam a usar o contexto Better Auth para prover `viewerId`, com `useQuery` protegido por `"skip"` enquanto não há sessão.
- Testes (`pnpm vitest run`) executados após as alterações para garantir regressão zero.
## Progresso recente (mar/2025)
Resumo do que foi implementado desde o último marco:
- Rich text (Tiptap) com SSR seguro para comentários e descrição inicial do ticket
- Componente: `web/src/components/ui/rich-text-editor.tsx`
- Comentários: `web/src/components/tickets/ticket-comments.rich.tsx` (visibilidade Público/Interno, anexos tipados)
- Novo ticket (Dialog + Página): campos de descrição usam rich text; primeiro comentário é registrado quando houver conteúdo.
- Tipagem estrita (remoção de `any`) no front e no Convex
- Uso consistente de `Id<>` e `Doc<>` (Convex) e schemas Zod (record tipado em v4).
- Queries `useQuery` com "skip" quando necessário; mapeadores atualizados.
- Filtros server-side
- `tickets.list` agora escolhe o melhor índice (por `status`, `queueId` ou `tenant`) e só então aplica filtros complementares.
- UI do detalhe do ticket (Header)
- Prioridade como dropdown-badge translúcida: `web/src/components/tickets/priority-select.tsx` (nova Convex `tickets.updatePriority`).
- Seleção de responsável com avatar no menu.
- Ação de exclusão com modal (ícones, confirmação): `web/src/components/tickets/delete-ticket-dialog.tsx` (Convex `tickets.remove`).
- Correções e DX
- Tiptap: `immediatelyRender: false` + `setContent({ emitUpdate: false })` para evitar mismatch de hidratação.
- Validação de assunto no Dialog “Novo ticket” (trim + `setError`) para prevenir `ZodError` em runtime.
Arquivos principais tocados:
- Convex: `web/convex/schema.ts`, `web/convex/tickets.ts` (novas mutations + tipagem `Doc/Id`).
- UI: `ticket-summary-header.tsx`, `ticket-detail-view.tsx`, `ticket-comments.rich.tsx`, `new-ticket-dialog.tsx`, `play-next-ticket-card.tsx`.
- Tipos e mapeadores: `web/src/lib/schemas/ticket.ts`, `web/src/lib/mappers/ticket.ts`.
## Guia de layout/UX aplicado
- Header do ticket
- Ordem: `#ref` • PrioritySelect (badge) • Status (badge/select) • Ações (Excluir)
- Tipografia: título forte, resumo como texto auxiliar, metadados em texto pequeno.
- Combos de Categoria/ Subcategoria exibidos como selects dependentes com salvamento automático (sem botões dedicados).
- Comentários
- Composer com rich text + Dropzone; seletor de visibilidade.
- Lista com avatar, nome, carimbo relativo e conteúdo rich text.
- Prioridades (labels)
- LOW (cinza), MEDIUM (azul), HIGH (âmbar), URGENT (vermelho) — badge translúcida no trigger do select.
## Próximos passos sugeridos (UI/Funcionais)
Curto prazo (incremental):
- [ ] Transformar Status em dropdown-badge (mesmo padrão de Prioridade).
- [ ] Estados vazios com `Empty` (ícone, título, descrição, CTA) na lista de comentários e tabela.
- [ ] Edição inline no header (Assunto/Resumo) com botões Reset/Salvar (mutations dedicadas).
- [ ] Polir cards (bordas/padding/sombra) nas telas Play/Tickets para padronizar com Header/Conversa.
Médio prazo:
- [ ] Combobox (command) para responsável com busca.
- [ ] Paginação/ordenção server-side em `tickets.list`.
- [ ] Unificar mensagens de timeline e payloads (sempre `actorName`/`actorAvatar`).
- [ ] Testes Vitest para mapeadores e smoke tests básicos das páginas.
## Como validar manualmente
- Rich text: comentar em `/tickets/[id]` com formatação, anexos e alternando visibilidade.
- Prioridade: alterar no cabeçalho; observar evento de timeline e toasts.
- Exclusão: acionar modal no cabeçalho e confirmar; conferir redirecionamento para `/tickets`.
- Novo ticket: usar Dialog; assunto com menos de 3 chars deve bloquear submit com erro no campo.
---
## Atualizações recentes (abr/2025)
Resumo do que foi integrado nesta rodada para o núcleo de tickets e UX:
- Header do ticket
- Status como dropdownbadge (padrão visual alinhado às badges existentes).
- Edição inline de Assunto/Resumo com Cancelar/Salvar e toasts.
- Ação de Play/Pause (toggle de atendimento) com eventos WORK_STARTED/WORK_PAUSED na timeline.
- Layout dos campos reorganizado: labels acima e controles abaixo (evita redundância do valor + dropdown lado a lado).
- Tabela e comentários
- Empty states padronizados com Empty + CTA de novo ticket.
- Notificações
- Toaster centralizado no rodapé (bottomcenter) com estilo consistente.
- Título do app
- Atualizado para “Sistema de chamados”.
Backend Convex
- ickets.updateSubject e ickets.updateSummary adicionadas para edição do cabeçalho.
- ickets.toggleWork adicionada; campo opcional working no schema de ickets.
Próximos passos sugeridos
- Status dropdownbadge também na tabela (edição rápida opcional com confirmação).
- Combobox (command) para busca de responsável no select.
- Tokens de cor: manter badges padrão do design atual; quando migração completa para paleta Rever estiver definida, aplicar via globals.css para herdar em todos os componentes.
- Testes (Vitest): adicionar casos de mappers e smoke tests de páginas.
Observações de codificação
- Evitar `any`; usar TicketStatus/TicketPriority e Id<>/Doc<> do Convex.
- Não retornar Date do Convex; sempre epoch (number) e converter via mappers Zod.
## Atualizações recentes (out/2025)
- Cabeçalho de ticket agora persiste automaticamente mudanças de categoria/subcategoria, mostrando toasts e bloqueando os selects enquanto a mutação é processada.
- Normalização de nomes de fila/time aplicada também ao retorno de `tickets.playNext`, garantindo rótulos "Chamados"/"Laboratório" em todos os fluxos.
- ESLint ignora `convex/_generated/**` e supressões migradas para `@ts-expect-error` com justificativa explícita.
- Mutação `tickets.remove` não requer mais `actorId`; o diálogo de exclusão apenas envia `ticketId`.
## Atualizações recentes (nov/2025)
- Dialog de novo ticket redesenhado: duas colunas com botão “Criar” no cabeçalho, dropzone mais compacta, categorias primária/secundária empilhadas e rótulos explícitos.
- Validação do assunto relaxada para evitar `ZodError` prematuro; verificação manual permanece na submissão.
- Placeholder cinza claro "Escreva um comentário..." aplicado ao editor Tiptap e seção renomeada para “Comentários”.
- Linhas da tabela de tickets agora são totalmente clicáveis (mouse e teclado), reforçando acessibilidade e atalho de navegação.
- Toasts e layouts refinados para manter consistência entre criação, listagem e detalhe dos tickets.
## Atualizações recentes (out/2025)
- Tabela de tickets refinada com ícones de canal, prioridade ajustável inline e indicadores suavizados (fila/status/categoria) para reduzir ruído visual.
- Definido plano de migração para Better Auth com RBAC (admin/agent/customer), portal do cliente e painel administrativo para filas/categorias/agentes.
- Próximo passo: iniciar fase de implementação da autenticação real, substituindo middleware placeholder e alinhando Convex aos novos papéis.
- Better Auth agora usa banco SQLite local (`db.sqlite`) e o schema Prisma foi migrado com sucesso via `pnpm exec prisma migrate dev --name init`.
- Configuração do `postcss.config.mjs` corrigida para usar `@tailwindcss/postcss` como plugin executável, liberando a suíte do Vitest (`pnpm exec vitest run`).
- Script `pnpm auth:seed` cria/atualiza o usuário inicial (`admin@sistema.dev` / `admin123`) usando `better-auth/crypto` para hash de senha.
- Página de login refeita com layout em duas colunas (header + imagem lateral) e formulário integrado ao Better Auth (`LoginForm`).
- Middleware atualizado aplica RBAC inicial (clientes direcionados ao portal, rotas `/admin` reservadas a administradores) e helpers de role expostos em `src/lib/authz.ts`; página `/portal` criada como placeholder do futuro autosserviço.
## Próximos passos estratégicos
### Produto / Experiência
- [ ] Unificar revisão visual do modal de novo ticket com microinterações (estado de salvamento, validações inline).
- [ ] Implementar filtros salváveis e quick actions na listagem (ex.: alterar status diretamente).
- [ ] Exibir indicadores de anexos na tabela e nos cartões de “tickets recentes”.
### Técnica
- [ ] Corrigir configuração do `postcss.config.mjs` (plugin inválido impede execução do Vitest) e restaurar cobertura de testes automatizados.
- [ ] Formalizar camada de autenticação (Auth.js ou Clerk) com refresh de sessão e proteção de rotas no Convex (`auth.getUserIdentity`).
- [ ] Mapear RBAC inicial (admin/agente/visualização) e refletir nas mutations do Convex.
- [ ] Configurar ambientes `staging`/`production` do Convex com variáveis (.env) versionadas via doppler/1Password.
- [ ] Automatizar lint/test/build no CI (GitHub Actions) e bloquear merge sem execução.
### Administrativa / Operacional
- [ ] Inventariar acessos: quem possui permissão no Convex, GitHub e futuros serviços (Redis, email, armazenamento S3?).
- [ ] Criar checklists de onboarding/offboarding de agentes (criação de usuário, associação a filas, provisionamento de avatar).
- [ ] Definir plano de capacidade para armazenamento de anexos (quotas por tenant, política de retenção) e alertas.
- [ ] Preparar mock de integrações externas (e-mail entrante, WhatsApp) para futuras etapas.
- [ ] Documentar fluxo de suporte interno (quem revisa PRs, janelas de deploy, rollback).
Manter este arquivo atualizado ao concluir cada item estratégico ou quando surgirem novas dependências administrativas.
## Atualizações recentes (mai/2026)
- Login corporativo refinado com instruções revisadas para primeiro acesso e mensagens de erro totalmente em PT-BR.
- Script `pnpm auth:seed` executado para garantir o usuário administrador padrão (`admin@sistema.dev` / `admin123`).
- Toast de autenticação inválida agora informa "E-mail ou senha inválidos", alinhando o feedback com o restante da interface.
### Próximos passos imediatos
- [ ] Implementar fluxo completo de convites (criação, expiração, revogação) integrado ao Better Auth e Convex.
- [ ] Adicionar testes Vitest/E2E cobrindo dashboards, relatórios e guardas de RBAC no front.
- [ ] Mapear permissões de edição avançada para agentes (categorias, campos rápidos) antes de liberar novas mutações.
## Atualizações recentes (jun/2026)
- RBAC do Convex reforçado em times, filas, campos, SLAs e relatórios; todas as chamadas exigem `viewerId`/`actorId` conforme o papel (admin ou staff).
- Painel administrativo atualizado para consumir as novas assinaturas protegidas, com validações de sessão Better Auth e feedback de toasts.
- Dashboard principal passou a exibir métricas reais via `reports.dashboardOverview` e séries históricas por canal com `reports.ticketsByChannel`.
- Portal do cliente publicado com isolamento por `viewerId`, garantindo que clientes visualizem apenas seus chamados.
## Atualizações recentes (ago/2026)
- Convites Better Auth finalizados ponta a ponta: novos modelos Prisma, utilitários de servidor, rotas Next e tabela `userInvites` no Convex com sincronização e RBAC.
- Painel administrativo reorganizado com `CategoriesManager`, permitindo CRUD completo de categorias e subcategorias, inclusive cadastro em lote na criação.
- Campos personalizados de tickets agora são validados e persistidos no Convex (`tickets.customFields`) com normalização por tipo, `displayValue` e mapeamento seguro no frontend.
- Consultas e componentes que consomem `queues.summary` passaram a enviar `viewerId`, eliminando erros de autorização na UI de tickets.
- Suite de testes estendida com `invite-utils.test.ts` e configuração `vitest.setup.ts`, garantindo ambiente consistente com variáveis Better Auth.