Ficha Técnica
Papel
Criador e desenvolvedor
Stack
🔓 Rumo ao open source — o projeto roda em produção nos meus próprios sites e está sendo preparado para release público sob AGPL.
Google Analytics é pesado, invasivo e exagerado para a maioria dos sites. Alternativas privacy-first como Plausible e Fathom são ótimas — mas param no pageview. Este projeto é minha resposta: analytics cookieless que vai além do básico, com funnels, Web Vitals, error tracking e detecção de anomalias por IA, self-hostable de ponta a ponta.
O problema
Eu queria três coisas que nenhuma ferramenta entregava junto: (1) respeito real à privacidade — sem cookies, sem fingerprinting invasivo, compatível com LGPD/GDPR; (2) profundidade de produto — funil, retenção, fluxo de páginas, erros de JS, performance real do usuário; (3) posse do dado — meu banco, minha infra, meu custo.
As três peças
- SDK (
@racoelho/analytics) — TypeScript puro, ~3KB, zero dependências. Auto-captura pageviews, Web Vitals (LCP/CLS/INP/FCP/TTFB) e erros JS; métodos padronizados para e-commerce, vídeo, busca e eventos custom. Respeita DNT e consent explícito. - Ingestor — Bun + Hono, um pipeline de steps ordenados: valida → autentica (site key + allowlist de origem) → enriquece (geo, user-agent) → normaliza → deduplica → checa quota do plano → grava em batch.
- Dashboard — Next.js 15 multi-tenant com ~20 relatórios, workspaces com RBAC, billing por plano e insights de anomalia gerados por IA.
Arquitetura
Visão de componentes e infraestrutura (monorepo com 3 peças):
Fluxo de um evento:
Decisões técnicas que valem a pena contar
Visitantes únicos sem cookie. O identificador anônimo vive em localStorage, a sessão em sessionStorage — nada de cookie, nada de fingerprint. Na agregação, a contagem usa fallback em cascata (sessão → usuário → IP anonimizado), tolerando eventos incompletos sem inflar números.
Dedupe em três camadas. Pageview duplicado é a praga de qualquer analytics. Aqui ele morre três vezes: throttle local no SDK (mesmo path em menos de 2,5s), script Lua atômico no Redis com histórico de path por sessão no ingestor, e chave de idempotência SHA-1 no INSERT ... ON CONFLICT DO NOTHING no banco. Cada camada cobre a falha da anterior.
Rollups materializados. Dashboards não varrem events_raw: um cron agrega eventos em rollups diários/horários com breakdowns pré-computados (jsonb_object_agg por path, referrer, UTM, país, device). Janelas longas leem o rollup; janelas curtas ("última hora") caem no raw. É o clássico trade-off OLAP resolvido com Postgres puro.
Identity stitching. O visitante navega anônimo, loga na página 5 — e as 4 páginas anteriores? O rollup liga sessões anônimas à identidade via anon_id retroativamente, com predicado incremental por timestamp (a versão inicial, binária, nunca revisitava sessões — bug estrutural documentado e corrigido).
Resiliência no caminho quente. O ingestor tem circuit breaker de banco (abre após N erros, responde 503), quota "fail open" em erro de infra (nunca derruba o tracking do cliente por problema meu) e cache de credenciais com TTL curto.
Stack
TypeScript (monorepo npm workspaces) · SDK com tsup (ESM/CJS/IIFE) · Bun + Hono · PostgreSQL + Prisma · Redis · Next.js 15 + React 19 · NextAuth · Stripe · Anthropic SDK (insights) · Recharts.
Status
Em produção coletando dados reais dos meus sites (este blog incluso). Para o release AGPL faltam os ritos de open source: LICENSE, README raiz, exemplos de env, Docker e neutralizar o endpoint default do SDK. O código já nasceu com a separação certa — SDK MIT, plataforma AGPL.
Curtiu o projeto?
Se quiser conversar sobre esse projeto, arquitetura ou uma oportunidade de trabalho, é só me chamar. 🚀
contato@racoelho.com.br