Back to course overview
Module 1Foundations: from raw SQL to a semantic layer 12 min

Meet Percolate and the toolkit

Get the fabricated business, its SQL schema, and the starter repo you'll build on for the rest of the course.

You'll build against Percolate, a fictional direct-to-consumer subscription coffee company. The data is fabricated but coherent: it spans 2024–2025 and behaves like a real business — revenue grows over time, paid channels cost more to acquire customers, some subscribers churn.

The starter kit

Everything is in course-assets/semantic-agent/. The data lives in a SQLite database — a single file, no server to run — so you can query it from anywhere, and the agent can too.

course-assets/semantic-agent/text
data/
  schema.sql          # the raw operational schema
  generate_data.py    # deterministic data generator
  percolate.db        # the built database
semantic_layer/       # you dissect and extend this in Part 1
agent/                # you build this in Part 2
app/                  # you deploy this in Part 3

The schema (six tables)

  • customers — one row per customer: signup_date, country, region, acquisition channel, segment (Consumer/Pro).
  • products — the catalog: name, category, price, cost.
  • orders — order headers: customer, date, platform, status (completed/refunded).
  • order_items — order lines (the grain for revenue): product, quantity, unit_price, discount.
  • subscriptions — recurring plans: plan, start/cancel dates, mrr_amount, status.
  • marketing_spend — monthly ad spend per channel.

Notice the shape: two fact tables you'll aggregate (order_items, subscriptions), dimension tables that describe them (customers, products), and a standalone spend fact. This is a classic analytics layout — and exactly the kind of structure a semantic layer is built to tame.

Deterministic data

generate_data.py uses a fixed random seed, so everyone who runs it gets identical data — which means the example numbers in these lessons (like total revenue of $743,772.80) will match yours exactly. Reproducibility makes debugging your semantic layer far easier.