Ten commerce reports for your SourceMedium warehouse, ready to run, with every number linked to its published definition, its supporting records, and what the data can and cannot tell you. Use Codex or Claude Code to change a metric, rework a view, or build your next report. The app and its source code are yours.
Run it locally · See the reports · Open the demo
Every screenshot and the tour use synthetic sample data. The hosted demo reads SourceMedium's demo warehouse. No sign-in required.
- Reports that lead with the answer. Four primary metrics, a one-sentence readout of what moved, one large trend you switch without a new query, and the biggest changes by sales channel, all on one screen.
- Sales by geography. Valid-order revenue by shipping country and U.S. state on bundled, public-domain maps. No tiles, no map API keys, no geocoding. Every map group reconciles to an independently queried total.
- Every number explains itself. "About this number" on cards, charts, and table columns shows the published SourceMedium definition, the exact calculation, population, date basis, currency, and attribution behind it.
- Attribution you can inspect. Open any order and ask "Why attributed here?" to see the published winning source, its rank, and the supporting evidence, without raw click IDs or survey text.
- Honest data status. A compact strip under the filters says what the warehouse actually published about freshness, completeness, and quality, and never infers "all current" from a recent record date.
- Side-by-side creatives. Compare two to four creatives at identical scope, with minimum-spend and minimum-conversion thresholds applied after aggregation.
- Explore your data. Every published metric in one searchable list, grouped by SourceMedium's categories, with a plain-English drawer, a link to the report that shows it, and a hand-off to the coding-agent composer; field documentation and source availability sit beside it, served from the same adapter the reports use.
- Two comparisons at once. Every headline number compares with the previous period and the same period last year (or 52 weeks earlier), aware of what the range is: a full month against the previous month, a rolling week against the week before, a single day against the same weekday.
- A query cache. Repeated reads are served from a private cache inside the app, in memory and optionally in Cloudflare KV, with hard expiry and a Refresh button that bypasses it. Warm pages run no warehouse jobs.
- Exports with context. CSV downloads keep raw values. A JSON export adds the filters, timezone, currency verification, metric identities, and limitations from the same request.
Say you want to compare creative efficiency. Open Vibe code, pick a card, and describe the change:
On Delivery cards, replace Impressions with Cost / conversion so I can compare spend efficiency.
Before: impressions. After: cost per conversion.
Copy the prepared prompt into your coding agent. It includes the selected element, page, and applied filters. Your agent edits the repo; you review the result in a preview before publishing.
Real captures of a local customization using sample data. The starter keeps the default card; this example shows what you can change.
See the prompt and the code change
The metric already exists in the Performance view. This customization reuses it
in Delivery cards. In src/features/creatives/page.tsx,
replace the Impressions entry in the Delivery metrics:
- { label: "Impressions", display: formatCount(creative.impressions) },
+ { label: "Cost / conversion", display: formatMoney(creative.cpo, currency) },The existing calculation uses period spend / platform-reported conversions and shows an empty value when there are no conversions. No query or schema change is needed.
The Vibe code panel prepares context for an agent working in your repo. It does not run an agent inside the dashboard. See more things to ask.
Use Node.js 24 (22.22.1 or newer works) and pnpm 10.34.5.
git clone https://github.com/source-medium/sm-app-template.git my-data-app
cd my-data-app
pnpm install --frozen-lockfile
pnpm devOpen http://127.0.0.1:3000. Sample data works immediately, with no credentials, database setup, or AI API key. Or give your agent the setup prompt and let it guide you through connecting your warehouse and hosting the app.
Store selection travels between reports, and report filters live in shareable URLs. Period comparisons, CSV exports where available, chart-to-table views, and light and dark modes are already in place.
| Report | Start with this question |
|---|---|
| Overview | How did revenue, orders, and spend change, and which channels moved? |
| Performance tables | How do business metrics and platform totals compare by day, week or month? |
| All stores | Which stores are growing, and which need a look? |
| Paid marketing | Where is spend going, and what returns do platforms report? |
| Creatives | Which ads are delivering, at what cost, and how do they compare side by side? |
| Products | Which products and variants drive sales, and which gained or declined? |
| Retention | How do customers from each cohort return over time? |
| Orders | What happened with a particular order, and why was it attributed where it was? |
| Geography | Where are valid-order sales happening, and which shipping destinations are changing? |
| Explore your data | What do these metrics mean, where do they appear, and which evidence is available? |
Select a country to see its regions, or a U.S. state to see its orders. The table offers the same selection by keyboard, mobile stays table-first with an optional map, and map geometry loads only on this page. Unknown and unmapped destinations stay visible, and mapped-order coverage is shown against the same population as the total.
Definitions come from your warehouse's published semantic metric catalog, with the report's own population, filters, and date basis stated beside them. A report-specific calculation says so. If a published definition changes, the status strip raises a finding for maintainer review instead of silently changing a number.
Pick up to four creatives from the cards. The comparison fetches exactly those identities at the same store, dates, and filters, keeps platform-reported attribution labeled as such, and never declares a winner across platforms.
Compare stores, then drill into one
Search by store name, domain, brand, or ID. Names and available logos come from your warehouse; missing names fall back to a domain or store ID. All stores keeps each store's currency visible and avoids combining totals across currencies.
Use the naming conventions you already have
Filter campaign, ad set, or ad names by text such as [retargeting]. Combine
contains, does not contain, equals, and starts with rules, then inspect matching
names. Your text is treated literally, with no tag taxonomy to configure.
Filters travel with the report link. Creative metrics reflect the matching ad delivery, including when one creative appears in several campaigns.
Follow retention and lifetime value by cohort
Compare cohorts at the same age, filter acquisition channels, and switch the matrix between retention, repeat purchase, revenue, and gross profit measures. Ages that are not yet observable are marked distinctly from months with no data.
Each view owns its queries, sample data, and presentation. Copy the closest one
or remove the examples. Change your name, logo,
and navigation in app.config.ts, and your colors and fonts in
src/styles/tokens.css.
- Numbers are exact. Decimals stay exact through aggregation and export. Ratios divide aggregated numerators and denominators, never averaged daily ratios. Missing is never shown as zero, and fractional attributed conversions stay fractional.
- Populations stay distinct. Executive Summary orders are not valid-order counts, revenue per summary order is not AOV, and platform ROAS is not store marketing efficiency. The app says which one you are looking at.
- Scope travels, and nothing is dropped silently. Drill-downs carry store, dates, population, date basis, and compatible filters, and explain any transition they cannot preserve.
- Access is enforced everywhere. Every data function, route handler, and export checks the viewer and the store scope. SQL is written by developers and parameterized; browser input never becomes an identifier.
- Private by default. Pages are
private, no-store, queries run on the server, and nothing sensitive reaches telemetry or agent prompts.
Your agent follows the Cloudflare guide to connect the app and set up automatic deployments:
- Connect your data. An organization admin creates an app in your SourceMedium workspace's Dashboards & Apps page. Enter its configuration block privately.
- Choose who can view it. Use a shared password for a small trusted group, or Cloudflare Access for individual sign-in. Your agent helps you choose.
- Review, then publish. Push a task branch for a protected preview against
your data. Approve the change, then push
mainto deploy.
The default path uses Cloudflare Artifacts + Workers Builds. GitHub is optional. Workers Paid is required; see the guide for Artifacts availability and current costs.
Every viewer of a deployment sees the same data. For separate store audiences,
use separate deployments with APP_STORE_ID. See sign-in and store access.
If Dashboards & Apps says credentials are still being enabled, use sample data and
contact support. Do not use an admin credential.
The repo uses Next.js, React, TypeScript, shadcn/ui, Tailwind, and Recharts. It includes agent instructions, skills for adding pages, querying data and deploying, and checks for auth, store scope, data contracts, and browser accessibility (WCAG 2.2 AA with axe, keyboard, and 320px reflow coverage). Warehouse queries run on the server.
pnpm check # Format, lint, types, guardrails, and unit tests
pnpm test:e2e # Production build and browser tests| Guide | Read it when you need to… |
|---|---|
| Cloud setup | Set up source hosting, previews, and automatic deploys |
| Data connection | Connect a warehouse or replace a configuration block |
| Queries and metrics | Work with schemas, SQL, money, dates, and freshness |
| Sign-in and access | Choose a viewer guard or restrict a deployment to one store |
| Operations | Diagnose errors, rotate secrets, or roll back a release |
| Agent prompts | Add a report, change a component, or check a number |
0.1.0 preview. The tested hosting target is Cloudflare Workers. Fresh-account onboarding and self-service credential issuance still need end-to-end verification. See release evidence and remaining checks.
MIT license · Security · Support · Contributing
For a resumable local, preview and production setup, start with the setup guide. pnpm app:setup plan records sign-in and live intent; pnpm app:setup status checks current progress. Reconcile a reference period before treating an adapted dashboard as numerically verified.







![Creative Performance cards filtered to campaign names containing “[retargeting]”, with minimum spend and minimum conversion thresholds available.](/source-medium/sm-app-template/raw/main/docs/images/creatives.jpg)
