Banco do produto multi-tenant, GA4 e planilhas do cliente
Um modelo parametrizado por tenant, com janela de atribuição e marcação de estimado
Métricas de valor por tenant, isoladas e sem dado sensível
Portal, relatório mensal, extração e agente de IA
O que resolve
- Cada cliente recebe o mesmo cálculo de valor, sem uma query manual por pedido.
- Nenhum cliente enxerga dado de outro, nem credencial de integração.
- O número entregue diz quando é medido, estimado ou sem dado, e o cliente consegue conferir.
Perguntas de negócio que responde
Faça estas perguntas ao seu agente quando o caso estiver pronto.
O que você precisa
- Banco do produto conectado na Nekt, com o id do tenant em todas as tabelas ou alcançável por chave
- Uma tabela de configuração por tenant: id, camada de destino, data de início e fontes ativas
- A regra de valor combinada com os clientes: janela de atribuição, linha de base e tarifa
O que você recebe
- Tabelas por tenant, isoladas por camada e sem colunas sensíveis
- Relatório mensal de valor com mês fechado, comparação e alertas
- Portal ou extração para o banco do cliente alimentados pelo mesmo modelo
- Um agente de IA que responde por cliente sem misturar dados
Onde ativar
Sincronize a camada de cada tenant para o banco do portal (Postgres, Supabase ou S3) e mostre o tipo do valor ao lado do número.
Uma linha por tenant com mês fechado, comparação e alertas, que o CS leva para a reunião de resultado.
Responde o CS e o próprio cliente sobre um tenant por vez, com a janela e a marcação de estimado já aplicadas.
O cálculo é simples; o trabalho está em parametrizar por tenant e combinar a regra de valor. Depois disso, cada cliente novo é uma linha de configuração. 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.
Clientes do SaaS pedem os próprios dados e uma prova de valor, e cada pedido vira uma query no banco de produção ou uma cópia da transformação com o id do cliente fixo no código. Há workspaces com centenas de cópias quase iguais, e um ajuste de regra precisa ser repetido em todas. Ao mesmo tempo, a métrica de valor tem detalhes que mudam o número: janela de atribuição, horário truncado pela integração, dia sem medição e tarifa ausente.
Como costuma ser feito, e a regra
Cada linha é um erro que já aconteceu na prática.
Escreva a transformação uma vez com o id do tenant como coluna e leia a lista de tenants de uma tabela de configuração (id, nome de exibição, camada de destino, data de início, fontes ativas, parâmetros como janela e tarifa). Cliente novo é uma linha nessa tabela. Cópias só se justificam quando o cliente tem fonte própria que não existe para os outros, e mesmo assim chamando o mesmo cálculo.
Na Nekt, permissão se dá por camada. Entregue cada cliente numa camada própria (ou num destino próprio) e nunca numa tabela compartilhada filtrada só na leitura. A tabela consolidada com todos os tenants fica numa camada interna, visível só para o time do SaaS.
Tabelas que têm o id do tenant são filtradas direto. Tabelas filhas sem essa coluna (itens, mensagens, insights) entram pela chave estrangeira da tabela dona; tabelas de referência entram só com as linhas que os registros do tenant usam. Confira que toda tabela copiada tem caminho até o tenant.
Mantenha uma lista fechada de colunas que nunca saem: client_secret, access_token, refresh_token, senhas, chaves de API e credenciais de integração. Exclua-as em toda tabela entregue, inclusive nas que vêm de conector padrão, como o client_secret do payment intent do Stripe.
Receita atribuída a uma mensagem, campanha ou automação conta só pedidos do mesmo cliente final feitos depois do envio e dentro da janela combinada (um caso real usa 3 dias). Cada pedido é atribuído a um único disparo, o mais recente antes dele. Valores em centavos são divididos por 100 uma vez.
Algumas integrações de pedido mandam só a data, com hora 00:00:00. Para cada tenant, olhe os últimos três pedidos: se todos têm hora, minuto e segundo zerados, trate o campo como data e compare a janela em dias; senão, como timestamp. Guarde a decisão na configuração do tenant.
Se falta um insumo (tarifa não cadastrada, medidor offline, integração parada), o resultado é nulo com uma coluna de motivo, nunca zero. Distinga erro de dado de decisão deliberada: um cliente que contratou só a medição em kWh tem economia em reais nula e sem alerta, não um alerta de tarifa incompleta.
Dias sem leitura podem ser preenchidos pela média do mesmo dia da semana no período real mais próximo, mas a linha leva uma marca (medido ou projetado). Nunca use um valor fixo de preenchimento. A linha de base de economia é a média por dia da semana na janela de monitoramento antes da automação; se a operação muda (por exemplo, o número de equipamentos), abra um novo regime de linha de base com data de corte.
Para provar impacto de uma funcionalidade, divida os itens do cliente em com e sem ela a partir da lista que o próprio cliente mantém, e compare visualizações, carrinho, compra e receita no mesmo período. O cruzamento é pelo id do item; sem id, pelo nome que começa com o nome cadastrado, ficando com um único casamento, o mais específico (nome mais longo).
Quando o produto grava tabelas derivadas próprias (prefixos como dw_ ou dwt_) ao lado das tabelas de aplicação, use as de aplicação, que são a fonte da verdade. Registre no context document as tabelas cujo nome engana (por exemplo, uma tabela chamada crédito que guarda cobranças), filtre soft delete (deletedAt nulo) e tire do relatório métricas cujo status nunca é preenchido na origem.
Como cada número entregue é marcado
Toda linha entregue ao cliente leva o tipo do valor, para o portal e o agente explicarem o número.
Definições
Armadilhas que já aconteceram
Uma transformação por cliente cresceu para centenas de versões; uma correção de regra deixou clientes com números diferentes para o mesmo cálculo.
Parametrize por tenant e migre as cópias para o modelo único.
Quando cada fonte conectada gera tabelas com o id do conector no nome, o id muda entre workspaces e se a fonte for reconectada; queries com o id fixo quebram.
Resolva o prefixo atual listando as tabelas antes de consultar e nunca grave o id no context document.
Uma sincronização completa da origem apagou meses de dados brutos que não existiam mais na API, e o relatório de valor perdeu o histórico.
Guarde um backup congelado do histórico já entregue e reprocesse por cima dele.
Planilhas de cadastro trouxeram vírgula decimal, ponto de milhar, símbolo de moeda, células vazias e erros como #DIV/0!.
Converta com tentativa segura e transforme erro e vazio em nulo, nunca em zero.
O mesmo campo de data veio como ano-mês-dia, mês/dia/ano, dia/mês/ano e mês por extenso, conforme o tenant.
Tente os formatos em ordem fixa, registre o formato por tenant e marque o que não converteu.
Dia da semana numerado de forma diferente entre Spark e Athena trocou a linha de base de dia, e feriados móveis como a Páscoa ficaram de fora.
Use um calendário único com dia útil e feriados nacionais e móveis, gerado uma vez.
Teste de aceitação
O caso está pronto quando todos os itens passam.
- Para um tenant e um mês fechado, a receita atribuída bate com o painel do próprio produto (diferença abaixo de 1%) e nenhum pedido aparece atribuído a dois disparos.
- Em cada camada de cliente existe exatamente um id de tenant distinto em todas as tabelas.
- Nenhuma tabela entregue contém colunas da lista de proibidas (client_secret, access_token e afins).
- O número de linhas marcadas como projetado é igual ao de dias sem leitura, e não existe economia zero em linha sem tarifa.
- Adicionar um tenant de teste exige só uma linha na configuração e gera o relatório dele na próxima execução.
Pacote para o agente
Cole no Claude, ChatGPT ou outro cliente com o MCP da Nekt conectado.
Dados entregues aos clientes do SaaS - Tenant = cliente do SaaS. A lista de tenants e seus parâmetros (camada de destino, data de início, janela de atribuição, tarifa, formato de data) está na tabela de configuração de tenants. - Toda pergunta sobre um cliente filtra um único tenant. Nunca misture tenants numa resposta para um cliente. - A camada de cada cliente é a fronteira de permissão. A tabela consolidada é interna. - Nunca exponha client_secret, access_token, refresh_token, senhas ou chaves de API. - Receita atribuída: pedidos depois do disparo e dentro da janela do tenant (padrão de 3 dias), cada pedido no disparo mais recente. Valores em centavos divididos por 100. - Tenant com horário de pedido truncado (00:00:00) compara a janela por data. - Valor nulo significa sem dado; leia a coluna de motivo. Nulo não é zero. - Linhas com tipo_valor = projetado são estimadas pela média do mesmo dia da semana. Diga que são estimadas. - Relatório mensal: mês fechado anterior contra o mês antes dele. - Use as tabelas de aplicação, não as derivadas com prefixo dw_ ou dwt_. Filtre registros com deletedAt preenchido. - Se o conector gera tabelas com prefixo de id, descubra o prefixo listando as tabelas antes de consultar. Exceções por cliente: - <cliente>: janela de atribuição de <n> dias em vez de 3. - <cliente>: contratou só a medição; economia em reais fica nula e não gera alerta. - <cliente>: linha de base trocada em <data> por mudança na operação; antes e depois são regimes separados.
Construa no meu workspace Nekt o caso "Dados entregues aos clientes do SaaS" seguindo as regras em https://academy.nekt.com/industrias/saas/dados-entregues-aos-clientes.md. 1) Encontre as tabelas de origem e confirme as colunas usadas pelas regras. 2) Crie uma transformação no grão indicado aplicando todas as regras. 3) Rode o teste de aceitação e me mostre o resultado de cada item. 4) Crie o context document do caso no workspace, com as exceções dos meus clientes em aberto para eu preencher.
Variações
Quando o conector é de uma conta por fonte, cada cliente entra como mais uma fonte no mesmo modelo, com a conversão canônica combinada (ex.: um evento de cadastro no GA4).
Em vez de métricas, a cópia filtrada das tabelas do tenant para o banco dele, com a mesma propagação por chave e a lista de colunas proibidas.
O mesmo desenho serve para painéis por setor: uma camada por área, com o cálculo de atingimento no pipeline e não no agente.