dim_data_dictionary that is active and synced in the selected Metabase connection. Models do not require a supported metric, a Date column or a Store column. Empty tables remain available. Model and column descriptions come from the dictionary; field IDs and types come from Metabase’s synced schema. Nested child fields and internal columns are omitted from the model projection, while public top-level arrays and distributions remain available.
Include the dictionary’s exact dataset_name values for the models you want in your connection’s Only these… dataset list. Preserve existing entries. Your key must already have access; changing this list does not grant permissions. The plan reports documented tables that are missing or unsynced instead of silently omitting them. Tables outside the dictionary, including backups, are not installed as managed models. Supported metrics are a separate subset, so a model can be useful even when its metrics cannot be imported safely.
Set up with a coding agent
Copy one prompt into a coding agent with terminal access, such as Codex or Claude Code. You do not need to fill in a command first: the agent should discover what it can and ask for missing inputs together. Provide private file paths for credentials, never their contents. You may need to complete account, key-download or browser-upload steps yourself. Both prompts use the same adapter and metric definitions. The download includesAGENTS.md with its commands, ownership rules and verification steps. The agent should show you a plan before changing your Metabase content. The adapter manages its own subcollection; adding its cards to an existing dashboard is a separate, reviewed change.
- Start from scratch
- Use existing Metabase
Install and refresh the foundation
For repeatable setup, download the customer-run adapter and its SHA-256 checksum. It runs locally with Node.js 22 or later and supports Metabase 0.64.x, including the tested 0.64.1 release. It uses your existing Metabase BigQuery connection to read SourceMedium’s metric catalog. It does not need another warehouse key, change warehouse permissions or send credentials to SourceMedium.- Finish connection steps 1–3 in Connect Metabase. Include your metadata dataset when using the catalog. Find the database ID in the URL under Admin → Databases. Create or choose a destination collection and take its ID from the collection URL. The adapter creates its managed SourceMedium foundation subcollection inside it; for later runs, pass the same destination, not the managed subcollection.
- Create a Metabase API key in your own instance with permission to run native queries on that connection and manage content in the destination collection. Save it in a private text file, outside the downloaded folder and source control. Keep its contents out of commands, chat and screenshots.
- Unzip the download. Replace the uppercase placeholders below with your URL, IDs, dataset names from Copy settings (no secrets) and private token-file path. Use HTTPS for a remote instance; HTTP is accepted only on localhost.
--store STORE_ID to set a store default. The retention cutoff defaults to the previous completed UTC month; use --as-of-month YYYY-MM-01 for another completed month. Keep those options identical when planning and applying.
- Review
foundation-plan.json. Itschangesshow proposed definitions, itsunsupportedlist explains metrics that cannot be mapped faithfully, andretainedlists previously managed objects whose current definitions are unavailable. The plan contains content definitions and IDs, not your authentication token. Planning reads metadata and can create a BigQuery query job, but does not change Metabase content. - Run the same command with
--apply foundation-plan.jsonin place of--plan foundation-plan.json. Apply rechecks the plan before writing. It creates a managed SourceMedium foundation subcollection with models, supported metrics, the combined foundation dashboard and four separate dashboards when their source tables and required metrics are available. The combined dashboard includes only available sections, so an unavailable optional source does not hide the other tabs. It also creates namespaced SQL snippets from the same catalog. The KPI, trend, daily, weekly and paid questions reference those shared calculations while preserving required native date filters. Product, purchase-mix, deduction and cohort recipes retain their explicit population and calendar contracts.
SM_METABASE_V1 ownership line from the copy only; otherwise the duplicate can conflict with the managed identity. If a managed definition conflicts, preserve or copy your custom version, then restore the managed definition before updating it. A changed or incomplete pending definition needs review; the adapter will not overwrite it automatically.
Planning exits 0 when it can produce a review. Apply exits 2 when conflicts remain and 1 on a failed request or stale plan. A failed apply can leave completed objects and marked pending objects. The next plan resumes unchanged pending objects; review it before retrying. To undo an installation, archive its managed subcollection and corresponding namespaced SQL snippets in Metabase. This does not revoke warehouse access.
The adapter handles unfiltered sums, scalar counts (including distinct counts), averages, minima/maxima and same-table ratios when the catalog has a physical DATE time dimension and standard time grains. It reports other metric families individually. Models and metrics support visual exploration; snippets supply the same canonical calculations to the native dashboard cards. Metabase’s saved-question endpoint accepts native template parameters, so this keeps the cards’ required date widgets working when opened individually as well as on dashboards. Check the default date, store, currency and channel selections before using results. Use Monday-start weeks when reconciling with SourceMedium’s weekly recipe; visual query-builder calendars follow your Metabase settings.
Explore with reusable models and metrics
For visual exploration, Metabase metrics let people choose an agreed calculation in Summarize, then change its filters and breakdowns without writing SQL. Start fromrpt_executive_summary_daily. It already contains SourceMedium’s reporting logic. An optional Metabase model can expose a smaller selection of its columns with readable names and descriptions. Keep the original grain and include date, sm_store_id and sm_channel. Apply date and channel selections in the questions, rather than baking a fixed period or online_dtc into the reusable model.
Choose one starting source for the metrics and their questions: the table itself, or the curated model. A metric defined on a table is not automatically available on a model wrapping that table. Models and metrics work with the read-only connection; warehouse transformations stay in SourceMedium’s dbt models.
Use your warehouse’s dim_semantic_metric_catalog as the definition source. The initial summary set is:
Create the simple metrics using the catalog’s aggregation and column. Define MER by referencing the saved net-revenue and ad-spend metrics, so it divides the aggregate inputs. Preserve a null result for zero spend. Include the canonical metric name and definition source in each metric’s description. Curate Date, Store and Channel as its dimensions, with Date as the default dimension.
These are summary-system measures, not valid-order or unique-customer measures. Keep the starter’s definitions and calendar caveats. Do not round the underlying order-count values, pool reporting currencies or average daily ratios. Add a bounded Date selection before running an exploratory question; use the starter’s clearable
online_dtc default for summary dashboard questions.
Metabase’s BigQuery connection does not automatically import or refresh SourceMedium’s metric catalog. Use the adapter’s plan/apply workflow for repeatable updates, or compare manually copied definitions with the current catalog. For metrics beyond this set, preserve filter_condition, metric_time_expression and dependency definitions. Cross-model ratios, cumulative windows and cohort measures require their own grain and population rules; use the validated SQL recipes instead of approximating them with a sum or average.
The optional Library published tables and Remote Sync features require a Metabase Pro or Enterprise plan. They can help curate and version your content, but do not import SourceMedium’s definitions automatically.
Revenue and buyers
ReplaceDATASET with your transformed dataset name. Configure date, channel and store exactly as in the starter, including its online_dtc channel default. Map all three dashboard filters to these questions too. Leave the source table unaliased for the field filters.
Revenue and deductions
Save as a table. Amounts retain their published signs: add signed discounts and refunds to gross revenue, rather than subtracting them again. Unreconciled difference makes any remaining adjustment visible; it does not identify its cause.New versus repeat purchases
Save as a table. Counts are the published order measures, not unique people. Classification coverage varies by source, so the two rows need not add up to the headline totals. Revenue per order is computed from each row’s totals, not an average of daily ratios.Weekly business review
Save as a table beside the starter’s daily table. Weeks start Monday. Only selected dates contribute: the first and last week can be partial.days_with_rows counts represented dates, not successful source syncs or complete data coverage.
Optional: paid marketing
Create a Paid marketing dashboard with the two tables below. Both userpt_ad_performance_daily:
Wire those variables to this dashboard’s Date, Store and Ad platform filters. In this table,
source_system is the advertising platform that delivered the ad, such as meta_ads or google_ads, and sm_channel is the sales channel associated with the ad. These questions cover every sales channel, so their spend can exceed the executive summary’s Online DTC spend.
Platform-reported revenue and conversions retain each platform’s attribution rules. They can overlap across platforms and do not reconcile to store revenue. ROAS is platform-reported revenue divided by spend; cost per platform conversion is spend divided by platform-reported conversions. These are not MER, incremental returns or fully loaded CAC. Spend retains negative credits. Compare money only with compatible reporting currencies.
Ad platform economics
Campaign economics
Keep platform, account and campaign IDs together: names and campaign IDs alone can collide. The SQL groups every campaign in the selection, ordered by spend. Metabase can truncate long results; check its truncation indicator before treating a ranking or export as complete.Optional: product quality
Create a Product quality dashboard with this table. Mapdate to Order Processed At Local Datetime, channel to Sm Channel and store to Sm Store ID in obt_order_lines. Use a required date-range filter and the same online_dtc default as the starter.
This uses valid orders by their processed date. Refunds attached to those orders may happen later; this is not a refund-event timeline and it need not reconcile to the executive summary’s sales-report totals. Refund amounts and units are shown with their signs inverted for readability; reversals can still be negative. Product identity includes source and product ID, so equal titles stay separate.
Missing cost is different from zero cost. The two counts cover real order lines only; zero may be legitimate. A positive missing-cost count makes the published gross-profit amount incomplete as a business estimate. This table does not estimate replacement costs.
Optional: retention and second purchase
Create a Retention dashboard with the table below. It uses the published cohort report without product filters. Keep the unsegmentedno_filters and all_orders slice; acquisition-attribute families overlap and must not be summed together.
Use this dashboard’s As-of month, Channel and Store filters. Update the as-of default as months complete. An as-of month is an observation cutoff, not an order-date range. The query includes the 12 acquisition months ending with that month, and only elapsed ages through the cutoff. Never select a future or unfinished observation month for a completed-month comparison.
Second-purchase rate is cumulative second-order count divided by cohort size. Month 1 is the next calendar month, not “within 30 days”. Lifetime revenue is cumulative net revenue per acquired customer; gross-profit lifetime value uses cumulative gross profit instead. These values retain the producer’s FLOAT64 precision. Compare cohorts at the same elapsed age, and inspect cohort size beside rates. Do not average rates across unequal cohorts or pool sales channels.

