Documento executivo — Apresentação à Diretoria Versão 1.0 · Para discussão e aprovação
Hoje, quando um cliente da ChatSkills encontra um problema na plataforma:
Resultado: insatisfação do cliente, churn evitável, e equipe de produto/CS reativa em vez de proativa.
Uma Central de Suporte nativa do WhatsApp integrada à plataforma ChatSkills, onde:
| Para o cliente | Para a operação | Para a diretoria |
|---|---|---|
| Canal familiar (WhatsApp) | Triagem automática | Métricas em tempo real |
| Resposta mais rápida | Mídia anexada de cara | SLA mensurável |
| Transparência do status | Histórico consolidado | Insights sobre produto |
| Sem instalar nada | Menos ping-pong de e-mail | Redução de churn |
Contexto: já usa o WhatsApp para receber treinamentos. Quando algo dá errado, manda mensagem no número da ChatSkills e abre um chamado em menos de 1 minuto.
Jornada típica:
1. Cliente: "Oi, tô com um problema na plataforma"
2. Bot: "Claro! Vou abrir um chamado. Qual a categoria?
🐛 Bug 🔐 Acesso 💳 Cobrança 📚 Conteúdo ❓ Outro"
3. Cliente: [clica em 🐛 Bug]
4. Bot: "Descreva o problema em uma mensagem"
5. Cliente: "Quando clico em iniciar curso, a tela trava"
6. Bot: "Pode anexar um vídeo ou print mostrando o que acontece?"
7. Cliente: [envia vídeo de 12s]
8. Bot: "✅ Chamado #2841 aberto!
🎫 Categoria: Bug
⏱️ Resposta em até 2h úteis
🔗 Ver status: https://chatskills.io/sup/8x4kT"
Contexto: acompanha vários chamados em paralelo, precisa de visão consolidada e ferramentas para responder rapidamente.
Funcionalidades:
Contexto: quer ver a saúde geral, identificar gargalos, comparar atendentes, prever necessidade de contratação.
Funcionalidades:
| Campo | Origem | Exemplo |
|---|---|---|
| ID | Auto-gerado | ticket_2841 (público: 8x4kT) |
| Cliente | WhatsApp + auth | feereira@gmail.com (Group: ChatSkills) |
| Telefone | 5511999999999 |
|
| Categoria | Cliente escolhe | bug / access / billing / content / other |
| Prioridade | Auto + manual | low / medium / high / critical |
| Status | Workflow | open → in_progress → waiting_client → resolved → closed |
| Descrição | Cliente | Texto livre (1ª mensagem) |
| Anexos | Cliente | URLs R2 das mídias enviadas (até 5) |
| Atendente | Atribuído | user_id (admin/CS) |
| SLA Resposta | Categoria | 2h úteis para bug, 30min para access |
| SLA Resolução | Categoria + prioridade | 24h / 8h / 4h |
| Histórico | Auto | Linha do tempo completa de mensagens + status changes |
| CreatedAt / UpdatedAt | Auto | Timestamps |
| CSAT | Pesquisa pós | 1-5 estrelas opcional |
| Categoria | Ícone | SLA Resposta | SLA Resolução | Auto-prioridade |
|---|---|---|---|---|
| 🐛 Bug | bug |
2h úteis | 24h | medium |
| 🔐 Acesso (não consigo logar) | access |
30min | 4h | high |
| 💳 Cobrança | billing |
4h | 48h | medium |
| 📚 Conteúdo (vídeo quebrado, etc) | content |
2h úteis | 24h | medium |
| 🚀 Sugestão | feature_request |
1 dia útil | N/A | low |
| ❓ Outro | other |
4h úteis | 48h | low |
A solução se encaixa na infraestrutura já existente (FastAPI + Redis + Postgres + R2 + Dashboard SSE). Reuso massivo, baixo custo de implementação.
┌────────────────────────────────────────────────────────────────────┐
│ WhatsApp Cloud API │
└─────────────────────────────┬──────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ Webhook /webhook/whatsapp (FastAPI — já existente) │
│ Reuso: parse_incoming, SessionManager, send_message, send_cta_url │
└─────────────────────────────┬──────────────────────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌──────────────────┐ ┌─────────────────────┐
│ Bot conduz │ │ Mídia anexada │
│ diálogo guiado │ │ → Upload R2 │
│ (router) │ │ → register_media │
└────────┬─────────┘ └──────────┬──────────┘
│ │
▼ │
┌────────────────────────────────────┘
│ ┌──────────────────────────────┐
└──▶│ TicketManager (NOVO) │
│ create() / update_status() │
│ add_attachment() / assign() │
└────────┬─────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌─────────┐ ┌────────┐ ┌──────────┐
│ Redis │ │ Postgres│ │ R2 │
│ session │ │ tickets │ │ midia │
│ broadcast│ │ history │ │ │
└─────────┘ └────────┘ └──────────┘
│
▼
┌──────────────────────────────┐
│ Dashboard SSE │
│ /support — kanban + cards │
│ /support/{id} — detalhe │
│ /support/stats — métricas │
└──────────────────────────────┘
app/services/support/manager.py — CRUD de tickets, lifecycleapp/routers/support.py — endpoints REST + SSE para o dashboardapp/routers/webhook.py — fluxo de abertura via WhatsAppindex.html existente — kanban + modal de detalhesupport_tickets, support_messages, support_attachments_static_router + _bot_say… automática)A funcionalidade NÃO é um sistema à parte. Entra como opção no menu principal do bot, ao lado de "Gerar Relatórios" e "Criar Conteúdo":
🤖 Menu Principal (após login via e-mail)
├── 📊 Gerar Relatórios
├── ✏️ Criar Conteúdo
└── 🎫 Abrir Chamado ← NOVO
E no dashboard, mais uma tab no nav superior:
[💬 Chat] [📋 Kanban] [⏳ Tarefas] [🔄 Workflow] [🎫 Suporte] [⚙️ Config]
↑ NOVA
Zero retrabalho na infra; aproveita 100% do que já existe.
-- Tabela principal: 1 linha por chamado
CREATE TABLE public.support_tickets (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
public_id varchar(8) UNIQUE NOT NULL, -- '8x4kT' (URL curta)
phone varchar(20) NOT NULL, -- WhatsApp do cliente
user_id varchar(50), -- system_user_id (se autenticado)
group_id varchar(50), -- escopo
email varchar(255),
category varchar(30) NOT NULL, -- bug | access | billing | ...
priority varchar(10) NOT NULL DEFAULT 'medium',
status varchar(20) NOT NULL DEFAULT 'open',
title varchar(255), -- 1ª linha da descrição
description text NOT NULL,
assigned_to varchar(50), -- atendente
sla_response_at timestamp,
sla_resolve_at timestamp,
resolved_at timestamp,
closed_at timestamp,
csat int, -- 1-5
created_at timestamp NOT NULL DEFAULT NOW(),
updated_at timestamp NOT NULL DEFAULT NOW()
);
CREATE INDEX support_tickets_status_idx ON support_tickets(status);
CREATE INDEX support_tickets_assigned_idx ON support_tickets(assigned_to);
CREATE INDEX support_tickets_phone_idx ON support_tickets(phone);
-- Histórico de mensagens (cliente, bot, atendente, sistema)
CREATE TABLE public.support_messages (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
ticket_id uuid REFERENCES support_tickets(id) ON DELETE CASCADE,
author_type varchar(15) NOT NULL, -- client | bot | agent | system
author_id varchar(50), -- agent user_id se aplicável
body text NOT NULL,
internal boolean NOT NULL DEFAULT false, -- nota interna (cliente não vê)
created_at timestamp NOT NULL DEFAULT NOW()
);
-- Anexos (vídeo/imagem/PDF)
CREATE TABLE public.support_attachments (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
ticket_id uuid REFERENCES support_tickets(id) ON DELETE CASCADE,
message_id uuid REFERENCES support_messages(id) ON DELETE SET NULL,
media_id varchar(50) REFERENCES media(id), -- reusa public.media!
url text NOT NULL,
type varchar(20) NOT NULL, -- video | image | document
bytes int,
duration int, -- ms (se vídeo/áudio)
created_at timestamp NOT NULL DEFAULT NOW()
);
Sprint focado, aproveitando ao máximo a infraestrutura já existente. Dia 1 entrega o MVP funcional ponta-a-ponta; Dia 2 adiciona polish, SLA básico, métricas e robustez para produção.
Foco: cliente consegue abrir um chamado pelo WhatsApp e o atendente vê em tempo real.
| Hora | Entrega | Detalhes |
|---|---|---|
| 1h | 🗄️ Schema do banco | Migration com 3 tabelas: support_tickets, support_messages, support_attachments (com FKs, índices e public_id curto para URL pública). |
| 2h | 🔧 TicketManager |
Service em app/services/support/manager.py — CRUD: create_ticket, add_message, update_status, attach_media, assign_agent, list_tickets com filtros. |
| 3h | 💬 Fluxo WhatsApp (bot) | Nova opção 🎫 Abrir Chamado no menu principal. Handler conduz: categoria (5 botões) → descrição livre → "envie vídeo/imagem ou pule" → confirma. SupportContext na sessão para multi-step. |
| 4h | 📎 Upload de mídia | Reuso de r2_uploader + register_media. Folder novo support-attachments/. Vincula media_id ao ticket. Suporta múltiplos anexos (até 5). Fallback gracioso. |
| 5h | 🎟️ Endpoints REST | app/routers/support.py: GET /api/support (lista + filtros), GET /api/support/{id} (detalhe + histórico), POST /api/support/{id}/reply, POST /api/support/{id}/status, POST /api/support/{id}/assign. |
| 6h | 📡 SSE + notificação cliente | Broadcast SSE em cada change para atualizar dashboard em tempo real. Status change envia mensagem WhatsApp ao cliente automaticamente (com botão CTA do link público). |
| 7h | ✅ Testes do backend | tests/test_support.py com mocks — criação, anexo, listagem, status change, assign. Helpers FakeTicketStore. Mínimo 10 testes passando. |
| 8h | 🔍 Smoke E2E + ajustes | Testar fluxo completo manualmente via WhatsApp + curl/postman. Corrigir bugs encontrados. Commit + PR de fim do dia 1. |
Estado ao final do Dia 1: o sistema já funciona — cliente abre chamado, dados ficam no banco, atendente pode listar e responder via API. Falta só a UI bonita.
Foco: experiência visual no dashboard, SLA, métricas e validação para produção.
| Hora | Entrega | Detalhes |
|---|---|---|
| 9h | 🎫 Aba Suporte no dashboard | Adiciona 1 tab no index.html existente. Kanban com 4 colunas (Aberto / Em análise / Aguardando cliente / Resolvido). Cards com cliente, categoria, ícone Lucide, badge de prioridade, tempo desde abertura. |
| 10h | 🔍 Modal de detalhe | Click no card abre modal: descrição completa, mídia inline (vídeo <video> / imagem <img>), histórico cronológico (timeline), campos de status/atribuição editáveis. |
| 11h | 💬 Responder via dashboard | Campo "responder" no modal que envia mensagem ao cliente via WhatsApp através do send_message. Salva em support_messages com author_type='agent'. Suporta nota interna (toggle). |
| 12h | ⏱️ SLA básico | Cálculo de sla_response_at e sla_resolve_at por categoria/prioridade no create_ticket. Card mostra ⚠️ vermelho se SLA estourado, 🟡 amarelo se faltam < 30min. |
| 13h | 📊 Métricas no header | Strip horizontal no topo da aba: Total / Em aberto / Em análise / SLA% / Tempo médio resposta. Atualizado via SSE. |
| 14h | 🎨 Filtros + busca | Filtros por categoria, prioridade, atendente, "só meus", "SLA estourando". Busca por texto livre (cliente/descrição). |
| 15h | 🧪 Testes E2E + UI | tests/test_support_routes.py com httpx — endpoints REST. Testes manuais de UI (abrir, filtrar, responder, mudar status, assign). |
| 16h | 🚀 Deploy + comunicação | Build da imagem + deploy. Treinamento rápido (15min) para o time de CS. Documentação interna mínima. PR final mergeado. |
Funcionalidades que não bloqueiam o lançamento — adições incrementais conforme uso real:
| Risco | Probabilidade | Impacto | Mitigação |
|---|---|---|---|
| Cliente abusa do canal (chamados frívolos) | Média | Baixo | Rate limit (3 tickets / cliente / dia), classificação automática |
| Vídeos grandes estouram custo de R2 | Baixa | Médio | Limite 30 MB / vídeo, expiração automática após 90 dias resolvido |
| Atendentes ficam sobrecarregados | Média | Alto | Round-robin + alerta de SLA + dashboard de carga em tempo real |
| Privacidade (conteúdo sensível em mídia) | Baixa | Alto | LGPD: opção de pedir deleção; URLs assinadas com expiração |
| Bot trava o fluxo num bug próprio | Baixa | Alto | Fallback para "fala com atendente humano" sempre presente; comando #humano |
| WhatsApp cobra por categoria de mensagem | Certa | Baixo | Notificações de status caem em "service" (gratuito 24h após interação) |
| Item | Duração | Pessoas | Esforço |
|---|---|---|---|
| Dia 1 — Core MVP backend + WhatsApp | 1 dia útil | 1 dev fullstack | 8h |
| Dia 2 — Dashboard + SLA + métricas + deploy | 1 dia útil | 1 dev fullstack | 8h |
| Total | 2 dias úteis | 1 dev | 16h |
| Iterações futuras (opcionais, sob demanda) | sob demanda | 1 dev | conforme prioridade |
Por que 2 dias é viável: o projeto já tem toda a infraestrutura pronta — webhook WhatsApp, sessões Redis, upload R2 com extração de metadata, Postgres, dashboard SSE, autenticação. A entrega é basicamente: (1) 3 tabelas + service novo, (2) novo handler no router já existente, (3) nova aba no dashboard já existente. Sem novos servidores, sem novas integrações, sem novas dependências.
O Dia 1 entrega a funcionalidade "no osso" mas plenamente funcional ponta-a-ponta. O Dia 2 deixa o produto pronto para produção — com SLA, métricas, filtros, testes completos e treinamento do time.
Custo de infraestrutura adicional: desprezível. Reusa Redis, Postgres, R2, dashboard, deploy Docker. Estimativa: + R$ 30/mês em armazenamento R2 para 1000 tickets/mês com mídia anexa.
Comparado a Zendesk, Freshdesk, Movidesk, etc:
| Critério | Soluções tradicionais | ChatSkills Suporte |
|---|---|---|
| Canal de abertura | E-mail / formulário web | WhatsApp nativo ✅ |
| Adoção do cliente | "Mais um app pra baixar" | Já tá no celular ✅ |
| Custo por usuário | US$ 50-100/atendente/mês | Embutido na licença ✅ |
| Setup | Dias/semanas | Horas ✅ |
| Integração com plataforma | API | Nativo ✅ |
| Mídia anexada | Upload manual | Direto pelo WhatsApp ✅ |
| Quando | O quê |
|---|---|
| Dia 0 (aprovação) | Diretoria aprova; backlog priorizado |
| Dia 1 (8h de execução) | Core MVP — backend + WhatsApp + endpoints + testes + smoke E2E |
| Dia 2 (8h de execução) | Dashboard kanban + modal + SLA + métricas + filtros + deploy + treino |
| Dia 3 (manhã) | Beta interno — time de CS abre chamados-teste e valida fluxo |
| Dia 3 (tarde) | Ajustes finais com base no feedback do beta |
| Dia 4 | Soft launch para um cliente piloto |
| Dia 7 | Liberação geral + comunicação aos clientes: "Agora abra chamado direto pelo WhatsApp 🎉" |