299 lines
15 KiB
Markdown
299 lines
15 KiB
Markdown
# 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.
|
||
|
||
## 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] Scaffold Next.js + Tailwind + shadcn/ui.
|
||
- [x] Ajustar layout shell (dashboard + sidebar) com tema solicitado.
|
||
- [x] Criar modulos base de dominio (schemas Prisma/Zod) ainda com dados mockados.
|
||
- [x] Preparar estrutura de paginas: `/tickets`, `/tickets/[id]`, `/play`.
|
||
- [x] Implementar Auth placeholder (cookie + middleware).
|
||
- [x] Conectar APIs/mutations reais (Convex) e sincronizar tipos no frontend.
|
||
|
||
## Proximas entregas sugeridas
|
||
1. Finalizar Auth placeholder e guardas de rota (Auth.js + middleware).
|
||
2. Implementar camada de dados real (Prisma Client + server actions) para tickets.
|
||
3. Adicionar formularios de criacao/edicao de ticket com validacao (React Hook Form + Zod).
|
||
4. Conectar timeline/comentarios a mutations otimizadas (UI otimista + websockets futuro).
|
||
5. Preparar testes basicos (unit + e2e mockados) e pipeline de CI inicial.
|
||
|
||
## 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`.
|
||
- Auth placeholder: cookie + middleware
|
||
- Login: `web/src/app/login/page.tsx`
|
||
- Middleware: `web/middleware.ts`
|
||
- Provider: `web/src/lib/auth-client.tsx` (garante usuário no Convex)
|
||
- 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 PT‑BR (status, timeline, toasts, etc.).
|
||
- Atualizações otimistas com rollback em erro + toasts de feedback.
|
||
|
||
## 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 PT‑BR.
|
||
- 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 PT‑BR.
|
||
- [ ] 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 PT‑BR.
|
||
- 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 PT‑BR (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 PT‑BR; 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: PT‑BR 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 PT‑BR.
|
||
- [ ] Skeleton/Loading onde couber.
|
||
- [ ] Mappers atualizados se tocar em payloads.
|
||
- [ ] AGENTS.md atualizado se houver mudança de padrões.
|
||
|
||
---
|
||
|
||
## 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.
|
||
- 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 dropdown‑badge (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é (bottom‑center) 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 dropdown‑badge 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 ny; usar TicketStatus/TicketPriority e Id<>/Doc<> do Convex.
|
||
- Não retornar Date do Convex; sempre epoch (number) e converter via mappers Zod.
|