← Back to Home

How It's Built

This site is a monorepo built with Astro, deployed on Cloudflare Pages, with analytics powered by PostHog and Supabase. Here's how the pieces fit together.


🏗️ Architecture

Data flows from user action to live dashboard:

CLOUDFLARE
Pages (eeshans.com) Worker (/ingest/*)
POSTHOG
Events Webhook Supabase destination
SUPABASE
Edge Function PostgreSQL Views
FRONTEND
PostgREST API React island Live stats

⚡ Tech Stack

Layer Tech Why
Framework Astro 4.x Static-first, islands for interactivity
Styling Tailwind CSS Utility-first, dark mode support
Islands React 19 Interactive components (stats, game)
Analytics PostHog Events, session replay, feature flags
Database Supabase (Postgres) Views, PostgREST API, edge functions
Hosting Cloudflare Pages Fast, free, global CDN
Proxy Cloudflare Worker PostHog reverse proxy (bypass blockers)
Monorepo pnpm workspaces Shared components across packages

📊 Analytics Pipeline

Real-time stats flow from user actions to the dashboard in ~5 seconds:

  1. User plays game → PostHog SDK captures ab_test_decision event
  2. PostHog webhook → Fires on event, sends JSON to Supabase Edge Function
  3. Edge Function → Validates, transforms, inserts into posthog_events table
  4. Postgres Viewab_test_stats aggregates totals, unique users, last 24h
  5. PostgREST → Frontend fetches /rest/v1/ab_test_stats
  6. StatsCard → React island renders live numbers with loading states

📁 Monorepo Structure

ds-apps-main/
src/
pages/ — Routes (index, projects, contribute, stack, writing)
content/post/ — MDX blog posts
components/ — Site-specific components
packages/
shared/ — ProjectCard, Timeline, Header, projects.yaml
ab-simulator/ — Standalone game app
analytics/
notebooks/ — Jupyter analysis

🔗 Key Files


🚀 Adding a New Project

Bootstrap a new project in 8 steps:

  1. Add to projects.yaml — id, name, status, description, tags
  2. Create packagepackages/{project-name}/ with Astro config
  3. Add stats config — Supabase view name, display labels
  4. Create Supabase view — Aggregate events for stats
  5. Create hub page/projects/{id}.astro
  6. Add aiStory — Bullets describing AI collaboration
  7. Write blog post — With projectId: {id} frontmatter
  8. Update Timeline — Move from coming-soon → in-progress → live

✍️ Writing Workflow

Blog posts live in src/content/post/ as MDX files:

frontmatter example:
title: "How I Built the A/B Simulator"
publishDate: 2025-11-30
tags: ["data-science", "analytics"]
projectId: "ab-simulator" ← links to hub
featured: true ← shows on home

Posts with projectId appear in the project hub's "Related Content" section via getPostsByProject().


🔮 What's Next

In Progress

Prompt Debugger

Visualize and iterate on LLM prompts

LLM APIsReact
Coming Soon

Data Story Generator

Turn SQL queries into narrative insights

SQLLLMsVisualization
Coming Soon

Marketing Mix Modeling Explorer

Interactive tool for understanding MMM

marketingmedia-mix-modelcausal inference