Modelo de Dados

O Growth Brain não inventa dados — ele raciocina em cima dos seus. Antes de qualquer análise, a base do cliente precisa refletir 4 tabelas canônicas que cobrem identidade, monetização, comportamento e custo. Essa página explica o contrato mínimo pra rodar growth operations com confiança.

Leitura de 8 minutos Este documento descreve o modelo de referência. Casos reais podem ter mais tabelas, nomes diferentes ou granularidades específicas — o importante é que o conteúdo informacional exista em algum lugar auditável.

Por que começamos pelos dados

A maioria dos projetos de growth falha não por falta de método, mas porque o time debate em cima de evidência fraca. Dashboard agregando errado, KPI com definição ambígua, métrica que muda de nome entre times. O Growth Brain só funciona bem em cima de uma fundação confiável — e é essa fundação que esta documentação te ajuda a construir.

01
Uma fonte da verdade
Um único lugar onde "usuário ativo" tem exatamente uma definição — não três diferentes em três dashboards.
02
Análise causal, não snapshot
Pra entender por que o churn subiu, você precisa de séries temporais e não de um número do último mês.
03
SQL auditável
Toda recomendação do agente vem com a query que gerou o número. Se a query estiver errada, você vê e corrige.
04
Sem lock-in
O Brain não armazena seus dados. A análise roda no seu warehouse e volta como texto pro agente — o dado nunca sai.

As 4 tabelas canônicas

Todo negócio recorrente precisa responder quatro perguntas: quem é meu usuário, o que ele paga, como ele usa, e quanto custou trazê-lo. Cada pergunta tem a sua tabela. Não misture.

MECE importa Nunca guarde evento financeiro em eventos nem comportamento em transacoes. Quando os conceitos se misturam, queries ficam cheias de WHERE event_name = 'purchase' e análise fica lenta e frágil.

Quickstart de dados

Não precisa construir tudo antes de começar. A ordem abaixo maximiza o tempo entre "começar" e "primeira análise útil".

1
Comece pela usuarios e transacoes
Com essas duas você já roda /retentionDrilldown, /cohortAnalysis e uma primeira versão da /growthEquation. É o mínimo viável pra ter análise de retenção e monetização.
2
Adicione eventos quando precisar de ativação
Sem eventos você consegue ver que o usuário churnou, mas não onde ele travou dentro do produto. Adicione quando o time quiser atacar M0→M1.
3
Feche o loop com custos
Sem custos, CAC é estimado. Com custos, você fecha LTV/CAC de verdade e consegue /reportAcquisition por canal com atribuição causal.
4
Atualize diariamente, não em tempo real
Growth não precisa de streaming. Batch diário (de manhã antes das 10h) é suficiente — e muito mais barato que manter pipelines near-real-time.

Uma nota sobre tipos

Esta documentação usa tipos genéricos. Se você roda em BigQuery, Snowflake ou Redshift, o mapeamento abaixo vale. Postgres também funciona, só preste atenção em JSON vs JSONB.

genérico
string
timestamp
date
decimal
integer
boolean
json
bigquery
STRING
TIMESTAMP
DATE
NUMERIC
INT64
BOOL
JSON
snowflake
VARCHAR
TIMESTAMP_TZ
DATE
NUMBER
NUMBER
BOOLEAN
VARIANT
postgres
TEXT
TIMESTAMPTZ
DATE
NUMERIC
BIGINT
BOOLEAN
JSONB

usuarios

Tabela dimensional com uma linha por usuário. Contém identidade, atribuição de aquisição (UTMs e afiliado), plano atual e marcos do ciclo de vida.

Campo
Tipo
Required
Descrição
user_idPK
string
sim
Identificador único e imutável. Nunca reusar. Nunca derivar de email.
signup_at
timestamp
sim
Momento exato da criação da conta. UTC. Granularidade mínima: segundo.
signup_source
string
sim
Canal top-level. Valores canônicos: organic, paid, affiliate, referral, direct.
utm_source
string
não
Origem UTM da primeira visita. Ex: google, meta, tiktok, newsletter.
utm_medium
string
não
Meio UTM: cpc, organic, email, affiliate, social.
utm_campaign
string
não
Campanha UTM. Nomenclatura consistente aqui é o que permite /reportAcquisition confiável.
affiliate_idFK
string
não
Se veio por afiliado, o id dele. Null quando não-afiliado. Usado no /reportAffiliates.
country
string
não
Código ISO 3166-1 alpha-2. Ex: BR, US, PT.
plan
string
sim
Nome do plano atual. Use os mesmos nomes em toda a base.
plan_type
string
sim
Ciclo de cobrança. Valores canônicos: monthly, annual, trial, free.
is_active
boolean
sim
Tem assinatura ativa hoje. Recalculado no batch diário.
activated_at
timestamp
não
Marco de ativação — o aha moment do seu produto. Ex: primeira transação concluída, primeiro uso relevante.
first_value_at
timestamp
não
Quando o usuário recebeu valor pela primeira vez. Pode ser igual a activated_at, ou anterior.
churned_at
timestamp
não
Quando cancelou ou expirou. Null enquanto ativo.
churn_type
string
não
Categoria: voluntary (cancelou ativamente) ou involuntary (falha de pagamento).
churn_reason
string
não
Motivo categorizado quando voluntário. Mantenha um enum curto (5-8 valores) — free text não agrega.
Boa prática Reserve activated_at pro marco que seu produto define como "usuário pegou no jeito". Essa coluna é a base pra calcular NURR (New User Retention Rate) corretamente.
SQL exemplo · contar novos por canal no último mês
SELECT signup_source, COUNT(DISTINCT user_id) AS novos, COUNTIF(activated_at IS NOT NULL) AS ativados, SAFE_DIVIDE( COUNTIF(activated_at IS NOT NULL), COUNT(DISTINCT user_id) ) AS ativacao_rate FROM growth_mart.usuarios WHERE signup_at >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) GROUP BY signup_source ORDER BY novos DESC;

transacoes

Tabela de fato com uma linha por evento financeiro. É a fonte da verdade pra receita, MRR, refunds e churn involuntário.

Campo
Tipo
Required
Descrição
transaction_idPK
string
sim
Identificador único da transação. Use o id do processador (Stripe, Pagar.me, etc.) quando possível.
user_idFK
string
sim
Referência para usuarios.user_id.
transaction_at
timestamp
sim
Momento efetivo da transação (data de pagamento, não de emissão).
transaction_type
string
sim
Valores canônicos: new, renewal, upgrade, downgrade, refund, chargeback, reactivation.
amount
decimal
sim
Valor em unidade monetária (não em centavos). Positivo pra entradas, negativo pra refund e chargeback.
currency
string
sim
Código ISO 4217. Ex: BRL, USD.
billing_cycle
string
não
Ciclo da cobrança: monthly, annual, one_time.
product
string
não
Qual produto / plano gerou a transação. Consistente com usuarios.plan.
payment_method
string
não
Método de pagamento: credit_card, pix, boleto, paypal.
is_first_purchase
boolean
não
Flag redundante mas útil — primeira transação positiva desse usuário.
discount_amount
decimal
não
Desconto aplicado (positivo). Ajuda a separar ticket bruto de líquido nas análises.
Renovação não é "new" O erro mais comum aqui: marcar toda cobrança mensal recorrente como new. Isso infla novos usuários e esconde problemas de churn. Só a primeira transação de um user_id é new. As seguintes são renewal, mesmo que sejam mensais automáticas.

eventos

Tabela de fato com uma linha por ação relevante do usuário dentro do produto. Não é log de tudo — é curadoria de eventos que importam pra análise de ativação, engajamento e retenção.

Campo
Tipo
Required
Descrição
event_idPK
string
sim
UUID único por evento. Necessário pra garantir idempotência na ingestão.
user_idFK
string
sim
Referência para usuarios.user_id. Eventos anônimos (pré-signup) podem ter anonymous_id em coluna separada.
event_at
timestamp
sim
Momento do evento. Use o timestamp do cliente; valide com server-side.
event_name
string
sim
Nome canônico em snake_case. Mantenha um catálogo fechado — não aceite nomes novos sem revisão.
event_properties
json
não
Payload estruturado específico do evento. Ex: {"plan_from":"monthly","plan_to":"annual"}.
session_id
string
não
Identificador da sessão que originou o evento. Útil pra análise de funil dentro de sessão.
source
string
não
Origem do evento: web, app_ios, app_android, api, backend.
device
string
não
Tipo de device quando aplicável: mobile, desktop, tablet.

Eventos canônicos recomendados

Não precisa instrumentar todos, mas se instrumentou, use exatamente esses nomes:

events catálogo mínimo
// aquisição e onboarding signup_started signup_completed email_verified // ativação (define o seu "aha moment") trial_started first_key_action activation_reached // engajamento recorrente session_started key_action_performed // expansão e contração plan_upgraded plan_downgraded cancellation_requested cancellation_completed reactivation_completed
Não jogue o analytics.js inteiro aqui Uma tabela de eventos boa tem ~15-30 nomes canônicos, não 300. Tracking poluído é pior que tracking ausente — o agente não sabe quais eventos importam e gera análise ruim.

custos

Tabela de fato com uma linha por canal-campanha-dia. Base pro cálculo de CAC real e pra cruzar aquisição com retenção via /reportAcquisition.

Campo
Tipo
Required
Descrição
cost_date
date
sim
Data do custo. Granularidade diária é suficiente.
channel
string
sim
Canal top-level. Consistente com usuarios.signup_source. Ex: google_ads, meta_ads, tiktok_ads, affiliate, content.
account
string
não
Conta ou subconta quando existem múltiplas (ex: diferentes MCCs no Google Ads).
campaign
string
não
Nome da campanha. Deve bater com usuarios.utm_campaign pra permitir join.
ad_group
string
não
Granularidade menor dentro da campanha. Opcional mas recomendado pra paid social.
cost_amount
decimal
sim
Custo total no dia pra essa combinação canal/campanha. Positivo.
currency
string
sim
Código ISO 4217 da moeda do gasto.
impressions
integer
não
Impressões do dia. Permite calcular CPM e detectar ineficiência de top funnel.
clicks
integer
não
Cliques do dia. Junto com impressions permite CTR.
Pra afiliado não tem API Afiliado raramente tem campo campaign. Deixe null e use affiliate_id no lugar — é o que o /reportAffiliates espera encontrar.

Checklist de qualidade

Antes de ligar o Growth Brain na sua base, passe esse checklist. Dados frágeis geram análise frágil — e o agente vai detectar e reclamar, mas é melhor evitar.

Chaves únicas validadas
Rode COUNT(*) vs COUNT(DISTINCT pk) nas 4 tabelas. Os dois valores têm que bater.
Chaves estrangeiras sem órfãos
Todo user_id em transacoes e eventos tem que existir em usuarios.
Timestamps em UTC
Evita horror de timezone nos cortes diários. O agente converte pra BRT só na hora de apresentar.
Enums consistentes
Valores de signup_source, channel, transaction_type, plan_type vêm de listas fechadas — não texto livre.
Monetário em unidade, não centavos
amount em reais (59.90), não em centavos (5990). Menos bug matemático, menos conversão mental.
Refund e chargeback com sinal negativo
Permite SUM(amount) retornar receita líquida direto, sem CASE WHEN espalhado.
Janela histórica ≥ 13 meses
Pra /cohortAnalysis ter M6 com 6 meses de observação e comparação year-over-year, precisa de pelo menos 13 meses disponíveis.
Freshness monitorado
O batch atualiza antes das 10h BRT? Tem alerta quando atrasa? Sem freshness, análise de "ontem" mente.
Catálogo de eventos congelado
Lista explícita de event_name aceitos. Novo nome passa por revisão antes de entrar.
Campaign UTM bate com campaign do custo
Sem isso, não tem como cruzar quem chegou (usuarios) com quanto custou trazer (custos).

Próximos passos

Com as 4 tabelas no ar e o checklist verde, você tem o que precisa pra ligar o Growth Brain. A próxima página cobre o setup do MCP no Claude Code.