diff --git a/agents.md b/agents.md index 26e5599..7aab815 100644 --- a/agents.md +++ b/agents.md @@ -176,6 +176,8 @@ Este repositório foi atualizado para usar Convex como backend em tempo real par - `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? })` @@ -204,3 +206,62 @@ Observações: - [ ] 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.