AI-native business intelligence: ask your warehouse questions in plain English, on governed metric definitions.
Live demo: https://www.freelancerportfoliohub.com/jameslee/projects/lumenboard/index.html
Lumenboard sits between a company's data warehouse and the people who make decisions with it. Every metric has one reviewed definition, an owner and a certification state in the semantic layer, and dashboards, scheduled reports and AI answers all compile their queries from it. Every AI answer shows the certified metrics it used, its filters and the generated SQL, so an analyst can check it in seconds.
This repository contains the marketing site (home, product tour, metrics catalog, pricing) and the live demo: a working
executive dashboard for Harbor & Pine Supply Co., a sample outdoor retailer, driven by a deterministic simulation so
every number reconciles across tiles, charts, tables and answers. The metric definitions, semantic layer, question
planner and sample warehouse live in a Python service (semantic/) that the Next.js app calls over HTTP.
- Executive dashboard — four tabs (Overview, Revenue, Retention, Acquisition) and four date ranges (7D, 30D, 90D, 12M), each compared with the prior period; tab and range are kept in the URL.
- Hand-rolled charts — SVG line/area charts with crosshair tooltips, stacked columns, ranked bars with prior-period ticks, a gross-to-net waterfall, a checkout funnel, sparklines and cohort heat maps. No chart library.
- Semantic layer — governed metric definitions in YAML (
semantic/definitions/), each with an owner, certification state, model, filters and dimensions. Definitions are validated when the service starts: every column, join, dimension and time grain a metric names must exist, and ratio metrics may not reference each other in a cycle. A compiler turns metric + dimension + filter requests into SQL, expanding ratio metrics into their component aggregates with safe division. - Ask Lumenboard —
POST /v1/askplans a question on certified metrics with a deterministic, rule-based parser (metric synonyms, dimensions, filters, time windows, grain, comparisons and rankings), compiles the plan through the semantic layer, runs it on the sample warehouse and returns a chart spec, a written explanation and the SQL. Questions the metrics can't answer get a hint, not a guess. An LLM planner can be plugged in; its plans are validated against the same definitions and fall back to the rules. - Sample warehouse — a DuckDB database seeded from the deterministic simulation (orders, order lines, products, sessions, media spend, shipments, inventory), so generated SQL runs as written and revenue reconciles with the dashboard by day, channel and category.
- Accessible, responsive — keyboard tabs, ARIA state on every control, tables and cohort grids that scroll inside their cards, and a layout that holds from 390px up.
Web app (repository root)
- Next.js 15 (App Router) and React 19, TypeScript (strict)
- Server components and server actions read the semantic service over HTTP (
API_URL) - Plain CSS (
app/globals.css) with design tokens as custom properties
Semantic service (semantic/)
- Python 3.12, FastAPI and pydantic, managed with uv
- sqlglot to parse, validate and rewrite SQL
- DuckDB for the seeded sample warehouse
- pytest
Start the semantic service (it seeds an in-memory warehouse on first start, about a second):
cd semantic
uv sync
uv run uvicorn lumenboard.api.app:app --reload --port 8000Then the web app, in a second terminal from the repository root:
cp .env.example .env.local # API_URL=http://localhost:8000
pnpm install
pnpm devOpen http://localhost:3000 for the site and http://localhost:3000/demo for the dashboard. The API's interactive docs are at http://localhost:8000/docs.
Try the Ask API directly:
curl -s localhost:8000/v1/ask \
-H 'content-type: application/json' \
-d '{"question":"Which channels grew fastest this quarter?"}' | jq '.answer.sql'
curl -s localhost:8000/v1/ask \
-H 'content-type: application/json' \
-d '{"question":"top 3 categories by revenue last quarter excluding footwear"}' | jq '.answer.narrative'Or compile and run a metric query without a question:
curl -s localhost:8000/v1/query \
-H 'content-type: application/json' \
-d '{"metrics":["aov"],"dimensions":["channel"],"timeRange":{"start":"2026-09-01","end":"2026-09-24"}}'cd semantic
uv run pytest # semantic layer, planner, warehouse reconciliation, API contract
pnpm typecheck && pnpm lint # web app, from the repository root| Variable | Where | Default | Description |
|---|---|---|---|
API_URL |
web app | http://localhost:8000 |
Base URL of the semantic service |
PORT |
service | 8000 |
Port the container listens on |
WAREHOUSE_PATH |
service | :memory: |
DuckDB file for the sample warehouse (seeded if missing) |
DEFINITIONS_DIR |
service | semantic/definitions |
Metric, model and governance YAML |
CORS_ORIGINS |
service | none | Comma-separated origins allowed to call the API from a browser |
PLANNER |
service | rules |
rules, or llm to plan with the command in LLM_COMMAND |
semantic/Dockerfile builds the service with the warehouse seeded at build time and listens on $PORT; on Railway,
point a service at the semantic/ directory and set the web app's API_URL to its URL.
app/
(marketing)/ home, product tour, metrics catalog and pricing pages
demo/ live dashboard
actions.ts server actions: load a dashboard panel, ask a question
globals.css
components/
ask/ Ask panel, answer card, SQL block
charts/ AreaChart, BarChart, HBarList, Waterfall, Funnel, Sparkline, lineage, tooltip
dashboard/ DashboardShell, Sidebar, Tabs, RangePicker, KpiTile, DataTable, CohortGrid, panels/
marketing/ page sections (hero, feature splits, catalog, pricing, FAQ)
site/ header, footer, logo
ui/ icons, buttons, tags, cards
lib/
api.ts typed client for the semantic service
charts.ts scales, ticks and chart geometry
data/ site copy (home, product tour, navigation)
types/ shared types, including the service's response shapes
semantic/
definitions/ metrics (one YAML file per metric), models, owners, governance and lineage
src/lumenboard/
semantic/ definition models, registry and validation, SQL compiler, YAML view, catalog
planner/ rule-based question parser, time phrases, pluggable LLM planner
ask/ curated investigations and warehouse-backed answers
dashboard/ ranges, buckets and per-tab view models
domain/ sample-workspace simulation, calendar, formatting, reference data
warehouse/ DuckDB seed and read-only executor
content/ pricing plans
api/ FastAPI app and routes
tests/
Dockerfile
public/ favicon and variable font
| Script | Description |
|---|---|
pnpm dev |
Start the web app with Turbopack |
pnpm build |
Production build |
pnpm start |
Serve the production build |
pnpm lint |
Lint with the Next.js ESLint config |
pnpm typecheck |
Type-check with tsc --noEmit |
pnpm format |
Format with Prettier |
uv run uvicorn lumenboard.api.app:app |
Serve the semantic service (semantic/) |
uv run pytest |
Run the service tests (semantic/) |
uv run lumenboard-seed data/wh.duckdb |
Seed a warehouse file (semantic/) |
