Tracking¶
Em produção. O módulo responde de onde vem quem compra — canal, campanha e peça — e mede a própria lacuna: quanto do que entra ele não conseguiu rastrear.
O eixo é o link rastreável. Quem clica é contado; quem escreve é amarrado ao clique; o que acontece depois vira evento; e todo número da tela é leitura derivada desses eventos.
Decisão: instrumentação nunca bloqueia a operação
AD-021, de 2026-09-12. Toda escrita de tracking acontece depois do commit da operação de origem e engole a própria exceção. Se a gravação falhar, a mensagem chegou, a resposta saiu e a venda fechou do mesmo jeito.
A taxonomia é de três níveis¶
| Nível | Tabela | O que é |
|---|---|---|
| Canal | tracking_channels |
Onde a pessoa estava: Instagram, YouTube, indicação |
| Campanha | tracking_campaigns |
O esforço: "Setembro 2026", "Lançamento" |
| Peça | tracking_pieces |
O anúncio ou conteúdo concreto: "Reels da bio" |
A árvore vem do cadastro, nunca de lista fixa na tela. Acrescentar um canal é operação de tela, não deploy — em Tracking › Taxonomia, desde 14/09/2026. Antes disso existia o cadastro no banco e nenhuma tela, o que tornava o módulo dependente de quem tem acesso ao servidor. Ver Configuração pelo cliente.
Do clique ao lead¶
O link público é /l/CODIGO, rota do backend — ela conta o clique e redireciona. Ver Deploy.
| Passo | Onde fica | Regra |
|---|---|---|
| Clique | tracking_clicks |
Robô conhecido é descartado, e o descarte fica registrado |
| Toque | tracking_touches |
A origem do lead: coletada pelo clique, ou informada à mão |
| Evento | tracking_events |
O fato: lead criado, etapa alterada, venda, perda |
O link leva uma mensagem pré-preenchida com o código. Quando a pessoa apaga o código antes de enviar, a conversa entra como não rastreada — e o clique continua contado.
Link não se apaga
Não existe rota de exclusão de link, de propósito. Link que já circulou continua sendo clicado, e apagá-lo deixaria clique órfão e origem ilegível.
Validade e retenção¶
O link tem ativação e validade. O clique cru expira em 13 meses, por tracking:purgar-cliques, agendado no dia 1 de cada mês.
O clique que virou origem não é cru, e não sai
tracking_touches exige click_id num toque coletado. O expurgo alcança só o que nenhum toque referencia — robô, curioso, quem clicou e nunca escreveu. O clique que virou toque é a prova da origem de um lead, e fica. O agregado não é afetado em nenhum caso: ele se reconstrói dos eventos.
Atribuição: a decisão foi tomada¶
Decisão: o modelo de atribuição é configuração, não código
Resolvida em 2026-09-12. A escolha entre primeiro toque e último toque é uma linha de configuração, alterável em tela por coordenação, e vale na requisição seguinte — sem deploy e sem reprocessar dado.
Isso é possível porque os toques são guardados inteiros: o modelo só escolhe qual deles leva o crédito. Trocar o modelo e reconstruir o agregado recredita todo o histórico sem reimportar nada.
| Modelo | Credita | Serve para |
|---|---|---|
| Primeiro toque | Quem trouxe a pessoa | Medir o que gera descoberta |
| Último toque | O toque anterior ao fechamento | Medir o que fecha |
Último toque ignora toque posterior à venda: um toque que veio depois de ela existir não a produziu.
As telas¶
| Tela | Caminho | Para quê |
|---|---|---|
| Visão geral | /tracking/dashboard |
Receita por origem, quatro indicadores, alertas, funil compacto, cobertura |
| Funil | /tracking/funil |
Onde vaza e quanto tempo cada etapa consome, por canal |
| Origem em árvore | /tracking/origens |
Canal, campanha e peça em árvore única |
| Central de Atendimento | /tracking/central |
Conversa, ficha e fila numa tela só |
| Links rastreáveis | /tracking/links |
Criar e desativar link |
| Taxonomia | /tracking/taxonomia |
Cadastrar canal, campanha, peça, tipo de evento e origem |
| Auditoria | /configuracoes/auditoria |
O que era, o que passou a ser, e quem mudou |
Todas exigem permissão própria. A de dashboard é separada da Central: quem atende o dia inteiro não precisa ver faturamento.
A lacuna é o assunto, não o rodapé¶
Lead sem origem conhecida é estado de primeira classe. Ele tem a sua fatia na receita por origem, a sua linha na cobertura e um nó próprio na árvore, em cada nível — "Não rastreado", "Sem campanha", "Sem conteúdo".
Descartá-lo faria a soma por origem não fechar com o total. E a lacuna é justamente o que a cobertura existe para medir: quanto do número da tela merece ressalva.
Zero e desconhecido não são a mesma coisa
Indicador que não pode ser calculado mostra — e diz por quê; nunca zero. Zero é um número e afirma que a coisa aconteceu nenhuma vez. É por isso que custo por lead aparece como não disponível: exige credencial do gerenciador de anúncios, que não está integrado. Inventar zero afirmaria que o anúncio saiu de graça.
Pela mesma regra: cobertura sem lead nenhum no período é —, não "0%"; e variação sem período anterior é "sem base de comparação", não "+100%".
O que o funil mede¶
Quem chegou a uma etapa ou avançou, ou ainda está lá, ou vazou — e as três parcelas fecham com o total. Sem a do meio, todo lead em atendimento apareceria como perda e o funil pareceria furado onde não está.
O tempo de cada etapa é a mediana, não a média: um lead esquecido meses numa etapa arrastaria a média e faria a etapa inteira parecer lenta.
Agregado diário¶
tracking_daily guarda a linha por dia, canal, campanha e peça. É cache, nunca fonte da verdade: apagá-lo inteiro não perde nada, porque tracking:rebuild-daily o refaz dos eventos.
Não existe caminho incremental, e isso é a decisão. Incrementar exigiria saber o que já foi contado, e o dia em que essa memória divergisse dos eventos ninguém descobriria — o relatório continuaria fechando, com o número errado.
Decisão em aberto: quando reconstruir
A reconstrução é comando de terminal, não rotina agendada. Enquanto "quando reconstruir" não tiver resposta de produto, o dashboard diz quando o agregado está atrás dos eventos e qual comando rodar — em vez de somar zero com cara de fato consumado.
O corte do dia é America/Sao_Paulo, feito uma vez na reconstrução: uma venda das 22h de São Paulo é do dia 12, não do 13.
Auditoria¶
A tela de auditoria mostra campo, valor anterior, valor novo, autor e ação — e distingue três autores: pessoa, sistema e IA. O recorte filtrado é exportável em CSV, uma linha por campo alterado.
Pessoa apagada continua sendo pessoa
audit_logs.user_id é anulado quando o usuário sai do sistema. Sem author_type, a ação de quem saiu da empresa passaria a parecer ação do sistema — e a apuração perderia o rastro. O tipo fica; o nome some, e a tela diz isso em palavras.
Resolvido: a auditoria tem uma tela só
Em 13/09/2026 as duas telas viraram uma, em Configurações › Auditoria — a nova, que é superconjunto da antiga: mesma tabela, mais o par anterior/novo, mais o tipo de autor, mais exportação. A antiga, em /tracking/auditoria, deixou de existir. A auditoria registra alteração de contrato, pagamento, aluno e sessão — o sistema inteiro —, e por isso não mora dentro de Tracking.
Instagram continua sem existir¶
O atendimento por Instagram segue desenhado e não construído: fila única com abas e cinco origens, sem nenhuma implementação. Instagram no sistema é só origem de lead e tipo de rede social.