Uma planilha financeira que alguém atualiza à mão já não aguenta o volume quando os dados chegam de mais de uma fonte. O Alpha Signal, plataforma real que construí e mantenho, processa mais de 8 milhões de linhas por dia em quatro serviços rodando sob Docker — banco, ETL, API e dashboard —, cobrindo EUA, Brasil e cripto, com um agendador que dispara 12 tarefas por conta própria todo dia útil, sem operação manual.
O padrão por trás disso não é específico de mercado financeiro: é dados em tempo real, cálculo, ação — e serve qualquer operação que precisa decidir a partir de volume alto. Dá para montar uma versão simplificada desse padrão sem replicar a escala inteira? Dá, e o ponto de entrada não muda: ingestão, score, e uma tela que atualiza sozinha.
O que você precisa
- Python 3.11+
- Conta Supabase (Postgres + Realtime) — a camada gratuita cobre o protótipo
- Node.js e Next.js para o dashboard
- Docker e Docker Compose
- Arquivos CSV de transações de exemplo, ou uma fonte real se já tiver
- Opcional: chave de API de LLM, só para explicar anomalias já sinalizadas — não para processar todas as linhas
- Tempo: mais de duas semanas para a versão completa com dashboard ao vivo
Passo 1: monte o pipeline de ingestão
Comece pela fonte mais simples: arquivos CSV numa pasta monitorada. As etapas são ler e validar o schema, normalizar datas, moedas e categorias, e inserir no Supabase em lote.
create table transactions (
id uuid primary key default gen_random_uuid(),
source text not null,
date timestamp not null,
description text,
category text,
amount numeric not null,
type text check (type in ('credit', 'debit')),
score numeric default 0,
flags jsonb default '[]',
created_at timestamp default now()
);
create index idx_transactions_date on transactions(date desc);
Resultado: rodando o processador contra um CSV de teste, as linhas aparecem na tabela transactions.
Passo 2: implemente o motor de regras
Regras configuráveis, cada uma soma um score e pode adicionar uma flag:
RULES = [
{"name": "alto_valor", "condition": lambda t: t["amount"] > 10000, "score": 8, "flag": "Transação de alto valor"},
{"name": "fora_horario", "condition": lambda t: t["date"].hour < 6 or t["date"].hour > 22, "score": 5, "flag": "Transação fora do horário comercial"},
{"name": "categoria_nova", "condition": lambda t: is_new_category(t), "score": 3, "flag": "Categoria não vista nos últimos 90 dias"},
]
Cada transação recebe a soma dos scores das regras acionadas, mais a lista de flags. Resultado: transações de teste com valor alto ou horário atípico aparecem com score maior que zero.
Passo 3: some detecção estatística de anomalias, IA só para explicar
Rodar um modelo de linguagem em 8 milhões de linhas por dia não cabe em orçamento nenhum — por isso a ordem importa. Primeiro, estatística simples (z-score ou desvio da média móvel de 30 dias por categoria) sinaliza os outliers. Só as transações sinalizadas passam por uma chamada de IA, para gerar uma explicação legível — nunca todas as linhas.
Prompt: "Analise esta transação sinalizada. Com base no histórico do cliente
(média por categoria, horários típicos, valores típicos), explique por que
ela parece anômala."
Resultado: as transações sinalizadas ganham um campo de explicação em texto, sem custo de IA nas outras milhões.
Passo 4: calcule agregações em tempo real e cacheie as métricas
Totais diários, médias móveis e tendências por categoria ou conta ficam caros de recalcular a cada requisição do dashboard. Um job separado, rodando em intervalo curto e independente da ingestão, atualiza um cache dessas métricas. Resultado: consultar o cache devolve as métricas do dia sem tocar na tabela de transações inteira.
Passo 5: construa o dashboard com Next.js e Supabase Realtime
Um componente cliente assina mudanças na tabela via postgres_changes:
const channel = supabase
.channel('transactions-changes')
.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'transactions' }, (payload) => {
// atualizar estado do dashboard com payload.new
})
.subscribe()
Filtros por período, categoria e conta completam a interface. Resultado: uma transação nova inserida no Passo 1 aparece no dashboard sem recarregar a página.
Passo 6: configure alertas e exportação de relatórios
Um alerta — Telegram, e-mail ou webhook — dispara quando o score de uma transação passa de um limiar definido, e a exportação em PDF inclui o período filtrado no dashboard. Resultado: uma transação de score alto notifica fora do dashboard, sem alguém precisar estar olhando a tela.
Passo 7: suba com Docker e agende a ingestão contínua
O Docker Compose reúne o worker de ingestão, a API, o dashboard e o job de agregação do Passo 4. Um agendador dispara a ingestão em intervalos regulares, sem depender de alguém rodar na mão.
docker compose up -d
Resultado: o pipeline completo rodando sozinho — dado entra, é pontuado, aparece no dashboard em tempo real, e os alertas saem quando o score justifica.
LEIA TAMBÉM · ExplicaçãoO que separa um protótipo de IA de um sistema em produção são três peças baratasMostrar IA funcionando uma vez é fácil. O difícil é deixar rodando todo dia sem ninguém olhando. Três peças simples — Docker para empacotar, healthcheck para vigiar, agendador para disparar — fazem quase todo o trabalho.O que pode dar errado
Dashboard não atualiza mesmo com o Realtime configurado — a tabela não foi adicionada à publicação: alter publication supabase_realtime add table transactions;. Erro comum e silencioso.
Rodar IA em cada uma das milhões de linhas por dia estoura o orçamento — estatística filtra primeiro, IA só analisa o que já foi sinalizado.
Dados de fontes diferentes chegando em formatos diferentes de data e moeda — normalize antes de gravar, nunca depois.
Consultas ficando lentas conforme a tabela cresce — índice em date desde o primeiro dia, não como correção depois.
Próximos passos
Adicionar fontes além de CSV — APIs bancárias, webhooks — sem mudar o schema da tabela. Score configurável por cliente ou conta, em vez de um conjunto único de regras global. Trocar polling por evento na ingestão, para reduzir a latência entre o dado existir e ele aparecer pontuado.
O pipeline prova o padrão dados em tempo real, cálculo, ação. Depois que ele roda sozinho, o desafio deixa de ser captar dado e passa a ser decidir o que fazer com o alerta.
