Dados · Histórico de estado

Histórico com SCD Type 2

Como cada cliente, contrato ou negócio estava em qualquer data passada, com o dono, o plano e o status da época, sem o estado de hoje reescrever o passado.

UsoComum
EsforçoMédio
Para quemEmpresas que precisam responder como algo estava numa data passada, com fontes que só mostram o estado de hoje.
Fonte

Tabelas que só guardam o estado atual

Regra

Uma versão por mudança, com início e fim de vigência

Resultado

O estado de cada entidade em qualquer data

Ativação

MRR, comissão, carteira, funil e agente de IA

O que resolve

  • O número de um mês passado não muda quando o cadastro muda hoje.
  • Cada fato é cruzado com o dono, o plano e o status vigentes na data dele.
  • O dado que a fonte apaga depois de alguns dias fica guardado.

Perguntas de negócio que responde

Faça estas perguntas ao seu agente quando o caso estiver pronto.

Qual era o plano e o status deste cliente no fim de março?
Quem era o responsável por cada negócio quando ele foi ganho?
Quantos contratos ou imóveis estavam ativos no último dia de cada mês?
Qual era o segmento da empresa quando ela comprou?
O que mudou neste cadastro na última semana, e quando?

O que você precisa

  • As fontes conectadas na Nekt, com o histórico (SCD Type 2) ligado nas tabelas de estado
  • A chave de negócio estável de cada entidade
  • A lista de campos cuja mudança importa para o negócio

O que você recebe

  • Uma tabela de versões por entidade, com início e fim de vigência
  • Uma visão só com a versão vigente para o dia a dia
  • Fotos de fim de dia ou de fim de mês para as métricas
  • Um agente de IA que responde como algo estava em qualquer data

Onde ativar

MRR e carteira retroativos

Movimentos de MRR, contratos ativos e imóveis em pauta calculados pela foto de fim de mês.

Comissão e metas

Cada venda cruzada com o dono, a equipe e a regra vigentes na data do ganho.

Agente de IA via MCP

Responde como algo estava em qualquer data e diz desde quando existe histórico.

Quer construir?

Ligar o histórico na tabela de origem é configuração. O trabalho está nas fotos de tabelas derivadas, que pedem notebook com merge, e em reconstruir o período anterior a partir de eventos ou faturas. O detalhado traz as regras de negócio, as armadilhas e o teste de aceitação. Ou mande tudo direto para o seu agente com o MCP da Nekt.

Ver detalhado
O problema

A maior parte das fontes devolve só a foto de agora. Quando o cliente muda de plano, de dono ou de status, o valor antigo é sobrescrito e todo relatório do passado passa a usar o valor novo. Numa base real, mudar o segmento, o executivo ou o valor mensal de uma empresa reescrevia todas as vendas antigas dela. Outras fontes só guardam 30 ou 45 dias, e a cada sincronização completa o passado encolhe.

Como costuma ser feito, e a regra

Cada linha é um erro que já aconteceu na prática.

O jeito comumA regra
01
Esperar alguém pedir o histórico para ligar.
Ligue o histórico na fonte, desde já

Na Nekt, ative o SCD Type 2 na tabela de origem. Cada mudança vira uma linha nova com _available_from (início da vigência), _available_until (fim, nulo na versão vigente) e _deleted. O histórico vale a partir do dia em que foi ligado: a primeira versão de cada entidade é o estado naquele dia, não na criação.

02
Contar contas pelo código substituto.
A entidade é a chave de negócio, não a substituta

Cada versão pode ganhar um código substituto novo. Numa dimensão versionada de corretora, os códigos mudavam a cada versão da mesma conta. Identifique a entidade pela chave de negócio estável (id da assinatura, código da conta, id do negócio) e use o código substituto só para ligar o fato à versão daquela data.

03
Cruzar a captação de março com o assessor atual do cliente.
Pergunta no passado usa o intervalo

O estado numa data é a versão em que _available_from é menor ou igual à data e _available_until é nulo ou maior que ela. Para cruzar um fato com uma dimensão (o assessor da captação, o dono do negócio ganho, o plano da fatura), use a data do fato, não a versão de hoje.

04
Somar a tabela de versões como se fosse o cadastro.
Vigente é _available_until nulo

Para o dia a dia, publique uma visão só com a versão vigente (_available_until nulo e _deleted falso) e mantenha a linha do tempo completa numa tabela à parte. Quem consulta a tabela de versões sem filtro conta cada entidade várias vezes.

05
Truncar o timestamp em UTC para data.
Vigência em UTC, corte no fuso do negócio

_available_from e _available_until são instantes em UTC. Converta para o fuso do negócio (America/Sao_Paulo) antes de cortar o dia ou o mês, senão mudanças feitas à noite caem no dia seguinte e a foto de fim de mês pega a versão errada.

06
Usar a primeira versão do dia, ou a última linha que cada entidade teve no mês.
Várias versões no dia: vale a última

O SCD grava uma versão por sincronização que encontrou mudança, então a mesma entidade pode ter várias versões no mesmo dia. Na foto diária, use a última versão de cada entidade em cada dia. Na foto de fim de mês, use a versão vigente no último instante do mês, com o mesmo corte para todas as entidades.

07
Contar versões como mudanças de status.
Versão nova não é evento de negócio

Uma versão nova pode ter mudado só o período de cobrança, a última fatura ou outro campo técnico. Para contar mudanças de status, de dono ou de plano, compare o campo com o da versão anterior. Colunas de controle como _nekt_sync_at nunca entram na comparação, e _available_from diz quando a sincronização viu a mudança, não quando ela aconteceu na fonte.

08
Tratar a tabela bruta como arquivo histórico.
Fonte com retenção curta pede um acumulador

Algumas APIs guardam poucos dias: eventos do Stripe por cerca de 30, analytics de e-mail por cerca de 45, coleções com TTL no banco. A sincronização completa reescreve a tabela com a janela vigente e apaga o resto. Acumule numa tabela própria por merge, com chave e dia, que só cresce, e nunca troque esse merge por overwrite.

09
Gravar a foto do dia por append, sem chave.
Foto de tabela derivada pede notebook

Uma transformação SQL reconstrói a tabela inteira a cada execução e não guarda passado. Para fotografar um número calculado (carteira, saldo, MRR do dia), use um notebook que lê a própria saída, mantém os dias anteriores e substitui só o dia atual. Assim, rodar duas vezes no mesmo dia não duplica a foto.

10
Recalcular todos os meses a cada execução.
Mês fechado não se recalcula

O resultado de um mês fechado é lido da foto congelada, não recalculado com a regra ou o cadastro de hoje. Correções posteriores entram como ajuste no mês em que foram descobertas. Numa base real, uma qualificação recalculada a cada execução fez o número de um mês encolher depois de apresentado.

Que tipo de tabela responde a pergunta

Classifique a fonte antes de responder qualquer coisa sobre o tempo.

Cadastro atualSó responde sobre hojesobrescreve o passado
Versões (SCD Type 2)Estado em qualquer data_available_from <= data < _available_until
Foto diáriaEstado no fim de cada dia1 linha por entidade e dia
Foto de fim de mêsFechamento congeladoúltimo instante do mês, no fuso local
Histórico de eventos da fonteQuando cada mudança aconteceupropertieswithhistory (HubSpot), stage_history (Bitrix24)
Última observação conhecidaCada entidade na sua data mais recenteinformar a defasagem entre entidades

Definições

Versão
linha da entidade válida de _available_from (inclusivo) até _available_until (exclusivo); a vigente tem _available_until nulo
Estado na data D
versão da entidade em que _available_from <= fim do dia D e (_available_until nulo ou maior), com D no fuso do negócio
Foto diária
última versão de cada entidade em cada dia, 1 linha por entidade e dia
Foto de fim de mês
estado de cada entidade no último instante do mês, no fuso do negócio, com o mesmo corte para todas
Início do histórico
menor _available_from da tabela; antes dele só há estado reconstruído por eventos, faturas ou histórico de etapa
Mudança de campo
versão em que o valor do campo difere do valor na versão anterior da mesma entidade
Vigência quebrada
entidade sem nenhuma versão vigente, ou com duas versões vigentes ao mesmo tempo
Data do negócio
data em que o fato aconteceu (criação, ganho, cancelamento); nunca _nekt_sync_at nem _available_from

Armadilhas que já aconteceram

Overwrite apagou a série

Uma foto diária foi sobrescrita por engano e quase três semanas de histórico tiveram de ser reconstruídas.

Ponha uma guarda antes de gravar: recuse saída vazia e aborte se algum dia já gravado desaparecer.

A sincronização completa comeu o arquivo

A sincronização completa de uma fonte de analytics reescreveu a tabela com a janela vigente e apagou mais da metade das linhas de uma vez.

Acumule numa tabela própria por merge e nunca use a tabela bruta como arquivo.

Vigência quebrada na fonte

Uma dimensão versionada vinda de um parceiro tinha contas sem nenhuma versão marcada como vigente, uma delas com dezenas de versões.

Teste uma versão vigente por entidade todos os dias e use o intervalo de datas, não a flag de vigente da fonte.

O passado com o dono de hoje

A comissão cruzava negócios ganhos em meses passados com o responsável atual, e quem trocou de carteira levava vendas que não fez.

Cruze pelo responsável vigente na data do ganho.

A primeira versão não é o começo

A primeira versão de cada entidade era a do dia em que o histórico foi ligado. Lida como se valesse desde a criação, ela atribuía o segmento e o plano de hoje a vendas antigas.

Registre o início do histórico e reconstrua o período anterior por eventos, faturas ou histórico de etapa.

Backfill com data de carga

Um backfill gravou atributos de contrato com a data da carga e contaminou o cálculo de expansão dos meses anteriores.

Marque as linhas de backfill e nunca use a data da carga como data do negócio.

Validado em dados reais. Na conta de Stripe da própria Nekt, cerca de 7 em cada 10 assinaturas já existiam antes do primeiro registro do histórico, então a primeira versão não é o começo da assinatura. Cada assinatura tem exatamente uma versão vigente e os intervalos são contínuos, sem buraco nem sobreposição. E só cerca de 1 em cada 5 versões novas mudou o status: a maioria mudou a última fatura ou o período de cobrança, por isso contar versões não é contar mudanças de status.

Teste de aceitação

O caso está pronto quando todos os itens passam.

Pacote para o agente

Cole no Claude, ChatGPT ou outro cliente com o MCP da Nekt conectado.

Markdown completo
Histórico e datas
- Antes de responder sobre o tempo, classifique a tabela: cadastro atual, versões (SCD Type 2), foto diária, foto mensal, histórico de eventos ou última observação conhecida. Não chame cadastro atual de histórico.
- Tabelas com SCD Type 2 têm _available_from, _available_until e _deleted. Versão vigente: _available_until nulo e _deleted falso.
- Estado numa data: _available_from <= data e (_available_until nulo ou > data). Converta de UTC para America/Sao_Paulo antes de cortar dia ou mês.
- Cruze cada fato com a versão vigente na data do fato (dono, plano, status, segmento), nunca com a de hoje.
- A entidade é a chave de negócio. Códigos substitutos mudam a cada versão.
- Versão nova não é mudança de status: compare o campo com a versão anterior.
- _nekt_sync_at e _available_from não são data do negócio. Use a data do evento.
- O histórico começa no menor _available_from da tabela. Antes disso, diga que não há histórico ou use a fonte de eventos indicada.
- Meses fechados vêm da foto congelada. Não recalcule com o cadastro atual.
Exceções por cliente:
- <cliente>: histórico de <tabela> ligado em <data>; antes disso, usar <tabela de eventos>.
- <cliente>: foto de fim de mês com corte às <hora> do último dia útil.

Variações

Histórico nativo da fonte

Quando a fonte guarda histórico (propertieswithhistory do HubSpot, stage_history do Bitrix24, log de eventos), use-o para o período anterior ao SCD.

Fotos de métricas

Para números calculados (saldo bancário, estoque, carteira), uma foto diária por merge, com retenção definida.

Webhook de mudança

Para CRMs sem histórico de etapa, um webhook grava cada mudança como evento, com o valor de antes e o de depois.