Case study / 01

PingLens - AI-Powered Web Analytics Platform

A production-ready, privacy-focused web analytics platform with an integrated AI 'Data Analyst' that uses Text-to-SQL to answer natural language questions about your data. Built with TypeScript, Express.js, React, and PostgreSQL.

Status
Selected work
System context
TypeScript, Node.js, Express.js, React
Source
Public repository

01 / System behavior

Interactive proof

A project-specific technical mechanism based on the recorded architecture and implementation context.

Interactive proofPingLens - AI-Powered Web Analytics Platform
Natural-language question
LLM provider
Generated SQL
Validation 01
Validation 02
Validation 03
Validation 04
Validation 05
Read-only database
Analytics response

Context and intent

Built as a production-ready alternative to Google Analytics, PingLens demonstrates that privacy and powerful analytics aren't mutually exclusive. The platform deliberately chose complexity over simplicity - not just pageview counting, but a full AI-powered analyst that understands natural language, generates safe SQL, and streams conversational responses.

The AI Text-to-SQL pipeline is the heart of the system: users ask questions like 'What were my top pages yesterday?' and the LLM generates PostgreSQL queries with full schema context. Every query passes through five security layers before execution. The dangerous keywords blocklist rejects INSERT/DROP/DELETE operations. Pattern matching catches SQL injection attempts (OR 1=1, UNION SELECT). Table validation ensures only 'events' and 'websites' are queried. The query executes via a read-only database role with SELECT-only grants. If the first attempt fails, the system retries once with error context - teaching the LLM from its mistakes.

03 / Architecture record

Architecture

A structured reading of the architecture recorded with this project.

Architecture recordPingLens - AI-Powered Web Analytics Platform
Customer Dashboard
Tracker Script
Backend API
Read the full architecture record

Three applications working together:

• Customer Dashboard (dashboard/) - React + Vite + TailwindCSS for website selection, real-time metrics visualization with Recharts, and AI chat interface with streaming responses • Tracker Script (tracker/) - Vanilla TypeScript (<5KB) with intelligent event batching, auto-flush timers, and sendBeacon fallback for reliable data collection • Backend API (api/) - Express.js with TypeScript handling event ingestion, analytics queries, AI Text-to-SQL pipeline, and multi-provider LLM abstraction

The API connects to PostgreSQL via node-postgres with two connection pools: a main pool for read/write operations and a read-only pool (ai_agent_reader role) for AI-generated queries. The AI pipeline validates SQL through regex blocklists, injection pattern detection, and table allowlists before execution.

LLM providers (OpenAI, Anthropic, Gemini) are abstracted via ILLMService interface with discriminated union ProviderConfig. The self-correction mechanism retries failed queries once with error context.

Docker Compose orchestrates the entire stack for local development. The production build uses multi-stage Dockerfiles with non-root users and health checks.

How the system is shaped

The tracker is engineered for performance and reliability: events queue in memory (max 50), auto-flush every 5 seconds, batch send with keepalive fetch, and sendBeacon fallback on page unload. Zero external dependencies. The entire bundle is <5KB minified.

Security was a first-class concern from day one: Helmet.js configures security headers, custom error classes sanitize messages in production, structured JSON logging includes request ID tracing for debugging, Zod schemas validate every API input, and zero 'any' types exist in production code. The SQL parser uses stateless regex (no /g flag) to avoid the lastIndex bug that causes alternating true/false results.

The LLM abstraction uses a discriminated union (ProviderConfig) with 'vercel' and 'gemini' kinds, allowing type-safe provider switching. OpenAI and Anthropic use the Vercel AI SDK's unified interface. Google Gemini requires custom streaming logic but presents the same ILLMService interface to consumers.

The test suite validates critical paths: SQL parser tests verify the stateful regex fix, injection pattern blocking, and legitimate CAST/DATE function allowance. Validation tests cover Zod schemas and IP/user-agent sanitization. Service tests mock LLM responses and verify retry logic. Tracker tests confirm queue batching and network fallback behavior.

05 / Selected highlights

Selected implementation notes

The decisions and workflows that carry the most explanatory weight.

  1. AI-powered natural language queries converted to SQL via LLM with multi-provider support (OpenAI GPT-4o, Anthropic Claude Sonnet 4, Google Gemini 2.5 Flash)
  2. Privacy-first analytics with no cookies, no fingerprinting - IPs resolved to country codes then immediately discarded for GDPR compliance
  3. Lightweight <5KB vanilla TypeScript tracker with intelligent batching (max 50 events), auto-flush every 5 seconds, and sendBeacon fallback for page unload
  4. Comprehensive SQL injection protection via five-layer defense: regex validation, pattern matching, table allowlists, read-only database role, and parameterized queries
  5. Self-correcting AI pipeline - if LLM-generated SQL fails, automatically retries once with error context for improved accuracy
  6. Production-grade security stack: Helmet.js headers, custom error hierarchy with sanitization, structured JSON logging with request ID tracing, Zod validation on all inputs

06 / Supported metrics

Verified project record

Applications
3
Test Coverage
93 tests
LLM Providers
3
Security Layers
5
Tracker Size
<5KB
Database Entities
2

Technology in context

TypeScript, Node.js, Express.js, React, Vite, PostgreSQL, OpenAI, Anthropic, Google Gemini, TailwindCSS, Recharts, Zod, Helmet.js, Docker, Jest, Vercel AI SDK

View source repository